I have a git branch (the mainline, for example) and I want to merge in another development branch. Or do I?
In order to decide whether I really want to merge this branch in, i'd like to see some sort of preview of what the merge will do. Preferably with the ability to see the list of commits that are being applied.
So far, the best I can come up with is merge --no-ff --no-commit
, and then diff HEAD
.
I do not want to use the git merge command as the precursor to reviewing conflicting files. I don't want to do a merge, I want to identify potential problems before I merge - problems that auto-merge might hide from me. The solution I have been searching for is how to have git spit out a list of files that have been changed in both branches that will be merged together in the future, relative to some common ancestor. Once I have that list, I can use other file comparison tools to scout things out further. I have searched multiple times, and I still haven't found what I want in a native git command.
Here is my workaround, in case it helps anyone else out there:
In this scenario I have a branch called QA that has many changes in it since the last production release. Our last production release is tagged with "15.20.1". I have another development branch called new_stuff that I want to merge into the QA branch. Both QA and new_stuff point to commits that "follow" (as reported by gitk) the 15.20.1 tag.
git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files
Here are some discussions that hit on why I'm interested in targeting these specific files:
https://softwareengineering.stackexchange.com/questions/199780/how-far-do-you-trust-automerge
Maybe this can help you ? git-diff-tree - Compares the content and mode of blobs found via two tree objects
git log ..otherbranch
git diff ...otherbranch
gitk ...otherbranch
Empty string implies HEAD
, so that's why just ..otherbranch
instead of HEAD..otherbranch
.
The two vs. three dots have slightly different meaning for diff than for the commands that list revisions (log, gitk etc.). For log and others two dots (a..b
) means everything that is in b
but not a
and three dots (a...b
) means everything that is in only one of a
or b
. But diff works with two revisions and there the simpler case represented by two dots (a..b
) is simple difference from a
to b
and three dots (a...b
) mean difference between common ancestor and b
(git diff $(git merge-base a b)..b
).
Pull Request - I've used most of the already submitted ideas but one that I also often use is ( especially if its from another dev ) doing a Pull Request which gives a handy way to review all of the changes in a merge before it takes place. I know that is GitHub not git but it sure is handy.
If you're like me, you're looking for equivalent to svn update -n
. The following appears to do the trick. Note that make sure to do a git fetch
first so that your local repo has the appropriate updates to compare against.
$ git fetch origin
$ git diff --name-status origin/master
D TableAudit/Step0_DeleteOldFiles.sh
D TableAudit/Step1_PopulateRawTableList.sh
A manbuild/staff_companies.sql
M update-all-slave-dbs.sh
or if you want a diff from your head to the remote:
$ git fetch origin
$ git diff origin/master
IMO this solution is much easier and less error prone (and therefore much less risky) than the top solution which proposes "merge then abort".
git log currentbranch..otherbranch
will give you the list of commits that will go into the current branch if you do a merge. The usual arguments to log which give details on the commits will give you more information.
git diff currentbranch otherbranch
will give you the diff between the two commits that will become one. This will be a diff that gives you everything that will get merged.
Would these help?
Short of actually performing the merge in a throw away fashion (see Kasapo's answer), there doesn't seem to be a reliable way of seeing this.
Having said that, here's a method that comes marginally close:
git log TARGET_BRANCH...SOURCE_BRANCH --cherry
This gives a fair indication of which commits will make it into the merge. To see diffs, add -p
. To see file names, add any of --raw
, --stat
, --name-only
, --name-status
.
The problem with the git diff TARGET_BRANCH...SOURCE_BRANCH
approach (see Jan Hudec's answer) is, you'll see diffs for changes already in your target branch if your source branch contains cross merges.
Adding to the existing answers, an alias could be created to show the diff and/or log prior to a merge. Many answers omit the fetch
to be done first before "previewing" the merge; this is an alias that combines these two steps into one (emulating something similar to mercurial's hg incoming
/ outgoing
)
So, building on "git log ..otherbranch
", you can add the following to ~/.gitconfig
:
...
[alias]
# fetch and show what would be merged (use option "-p" to see patch)
incoming = "!git remote update -p; git log ..@{u}"
For symmetry, the following alias can be used to show what is committed and would be pushed, prior to pushing:
# what would be pushed (currently committed)
outgoing = log @{u}..
And then you can run "git incoming
" to show a lot of changes, or "git incoming -p
" to show the patch (i.e., the "diff"), "git incoming --pretty=oneline
", for a terse summary, etc. You may then (optionally) run "git pull
" to actually merge. (Though, since you've already fetched, the merge could be done directly.)
Likewise, "git outgoing
" shows what would be pushed if you were to run "git push
".
Most answers here either require a clean working directory and multiple interactive steps (bad for scripting), or don't work for all cases, e.g. past merges which already bring some of the outstanding changes into your target branch, or cherry-picks doing the same.
To truly see what would change in the master
branch if you merged develop
into it, right now:
git merge-tree $(git merge-base master develop) master develop
As it's a plumbing command, it does not guess what you mean, you have to be explicit. It also doesn't colorize the output or use your pager, so the full command would be:
git merge-tree $(git merge-base master develop) master develop | colordiff | less -R
— https://git.seveas.net/previewing-a-merge-result.html
(thanks to David Normington for the link)
P.S.:
If you would get merge conflicts, they will show up with the usual conflict markers in the output, e.g.:
$ git merge-tree $(git merge-base a b ) a b
added in both
our 100644 78981922613b2afb6025042ff6bd878ac1994e85 a
their 100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
a
+=======
+b
+>>>>>>> .their
User @dreftymac makes a good point: this makes it unsuitable for scripting, because you can't easily catch that from the status code. The conflict markers can be quite different depending on circumstance (deleted vs modified, etc), which makes it hard to grep, too. Beware.
If you already fetched the changes, my favourite is:
git log ...@{u}
That needs git 1.7.x I believe though. The @{u}
notation is a "shorthand" for the upstream branch so it's a little more versatile than git log ...origin/master
.
Note: If you use zsh and the extended glog thing on, you likely have to do something like:
git log ...@\{u\}
Source: Stackoverflow.com