Reputation: 2366
I'm resolving some merge conflicts for a file and I'd like to see the evolution of the file on the master branch versus its evolution on my branch. I can't switch branches to look at the log history while I'm resolving the conflict. This how I view the log history typically:
git log --color --graph -- <path_to_file>
Now I'd like to include the branch as a command line argument like:
git log --color --graph --branch master -- <path_to_file>
Is something like this possible without having to checkout the branch?
Upvotes: 3
Views: 2253
Reputation: 60255
git log --first-parent -m --patch ...master -- that.file
will show you all changes to that.file
on master
since it diverged from your checkout, folding in the entirety of any changes brought in by merges (which the header will identify for you so you can easily explore further if you want).
Upvotes: 0
Reputation: 171
You can observe log history of all branches and their commits calling:
gitk --all
Upvotes: 1
Reputation: 487993
There's a fundamental (albeit tiny) glitch in the question itself, but you can get what you probably want very simply:
git log --color --graph master -- <path-to-file>
The double hyphen --
here separates the non-file arguments from the file (technically pathspec) arguments. It's not always required, but it is never a bad idea.
The rest of this answer is optional reading.
I said there's a glitch in the question itself. Here's why:
I'd like to see the evolution of the file on the master branch versus its evolution on my branch.
The "evolution of the file", as you put it, happens in commits and commits are on more than one branch at a time. Some commits in which the file evolved will be only on master
; some will be only on the current branch. Some will be on both branches.
A nice way to split things up is to examine only those commits that are only on master
, and only those commits that are only on the current branch. To do that, we would want to use Git's "symmetric difference" operator, spelled with three dots:
git log [options] master...HEAD [-- pathspecs]
Now, by itself (without --graph
or some other option) this still has a big problem: you can't tell, here, which branch the commit was found on. Using --graph
does fix that, but is a bit intrusive. An alternative is to use --left-right
. You might also want to add --topo-order
(because --graph
sets --topo-order
on its own): the --left-right
option marks each commit, with <
or >
, depending on whether it's found via the left side name—master
, in this case—or the right-side name, here HEAD
.
So, this ends up being:
git log --left-right master...HEAD -- <path-to-file>
or:
git log --left-right --topo-order master...HEAD -- <path-to-file>
Now the master
-side commits will be marked with <
, and the HEAD
/current-branch-side commits will be marked with >
.
You might still want to add -m
, if there are any merge commits in the range defined by the three-dot master...HEAD
syntax. See below for why. (You can also drop the name HEAD
entirely—it will be implied by the three-dot syntax—or use the one-character @
synonym, if you like.)
--
is requiredWhen you run a command like:
git log zorg
Git has a fundamental problem: is zorg
a branch or tag name, or a file name? If it's the former, the output from git log
will start at the commit identified by the branch or tag name, but if it's the latter, git log
will start at HEAD
, and turn on History Simplification and look only for commits that modify the specified file (skipping merge commits unless you add -m
).
Git decides whether zorg
is a branch or file name by the simple expedient of testing it as one or both. If there is a file (or many files within some directory) named zorg
in Git's index right now, zorg
can be a file name ("pathspec", really). If there is a branch or tag named zorg
, zorg
can be the branch or tag name. If it's both, well, bad things happen in some cases and some versions of Git.1
If there's no file named zorg
in Git's index, git log zorg
tries to use it as a branch name, even if you're looking for the commit that deleted the file. You must use git log -- zorg
to force Git to treat it as a file name (pathspec).
If it's ambiguous, the presence of the --
ensures that Git treats the name correctly, even if you have an old version of Git (see footnote 1).
1In particular, with git checkout
in Git versions predating Git 2.23, Git treats it as a file or directory name, not a branch name. This invokes the git checkout
mode that means destroy any uncommitted work in this file, which Git cheerfully does.
Upvotes: 3