I'm trying to push some code using $git push origin master
but I get the error
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
When I did $ git fetch origin master
then $ git diff master origin/master
I got a list of all the files and changes that were different between the two repos. However I am only interested in the list of files that have changed between the remote repository and the last time I did a $ git pull origin master
on my local box.
Is there a way I can do this?
git fetch git log --name-status origin/master.. Will show you what commits you are about to retrieve, along with the names of the files. Based upon this reply the command "git log --graph -p" is doing a nice job. It shows tree information about the history and code changes as well.
Find what file changed in a commit To find out which files changed in a given commit, use the git log --raw command. It's the fastest and simplest way to get insight into which files a commit affects.
The git fetch command downloads objects to the local machine without overwriting existing local code in the current branch. The command pulls a record of remote repository changes, allowing insight into progress history before adjustments.
No it does not. It will attempt to incorporate changes from the remote repository into the branch. It won't overwrite local files that it's not touching and it will notify you if there are issues with the pull. Additionally, a simple git pull will not have any impact on your remote repository.
git pull
is the same as git fetch
followed by git merge
(or git rebase
).
git fetch
shows which refs where updated. It will show something like:
a8e5e4e..295bf31 master -> origin/master
This means the last time you fetched master it was at a8e5e4e now it is at 295bf31. You can see the changed files with something like:
git diff --name-status a8e5e4e..295bf31
But maybe even more interesting is the output of gitk master...origin/master
after the fetch. This way you can inspect both the changes on your side and the changes on origin side.
michas' answer is the right one for the question as asked.
What if you don't have the old ref, i.e., the a8e5e4e
part of a8e5e4e..295bf31 master -> origin/master
? Probably you don't actually care: as he suggested, looking at master...origin/master
can be even more interesting.1 But, what does this three-dot ...
syntax actually mean?
The answer is in the git rev-list
documentation:
Another special notation is
<commit1>...<commit2>
which is useful for merges. The resulting set of commits is the symmetric difference between the two operands. ...
which I suspect is confusing enough wording (and actually git diff
uses a quite different meaning). But really, it's not that complicated.
Given some commits that could be drawn like this:
master origin/master
E G
| |
D F
\ /
C
|
B
|
A
what you have is a divergence at commit C
. You started work when master
and origin/master
both pointed to C
. Clearly, you committed D
and E
, and "they" (whoever they are) committed F
and G
. Commit C
, by the way, is called the merge base.
What master...origin/master
means is: find me C
, and then give me everything "up from there", on both the left and right sides. That is, all the commits on both master
and origin/master
, excluding any commits at-and-below the point where they first meet.
If you run gitk master...origin/master
you'll see just that:2 all the commits you made, and all the commits they made. But, if you run git diff flags master...origin/master
, git diff
throws most of this out. Instead, it finds the merge base C
,3 and diffs that against the right-hand side name.
Assuming you're on your master
branch (i.e., HEAD
simply means "master" anyway), you can shorten this even further. To see what files they modified since your and their branches diverged, just run:
$ git diff --stat ...origin/master # or --name-status, etc
Leaving the name out means HEAD
, so this is the same as HEAD...origin/master
which is the same as master...origin/master
.
If your git is new enough, @{u}
refers to "the current branch's upstream branch" (i.e., from master
, find origin/master
), so you can run:
$ git diff --stat '...@{u}'
(the quotes are to protect the braces from the shell; they may or may not be needed in your particular shell). This works even if you're on develop
with origin/develop
as its upstream, or featureX
with origin/featureX
as its upstream, etc.
1If you don't have gitk
, try:
$ git log --graph --boundary ...origin/master
(or '...@{u}'
as noted above). You need the --boundary
to include the merge commit. You might want to add --oneline --decorate
as well.
2Actually gitk
will show you the merge commit too, just like the command in footnote 1. That is, it uses --boundary
to include meeting-point commits (this is not quite the same as merge bases, but close enough).
3This assumes there is exactly one merge base commit. For these cases, that should be true. So, git diff
compares the tree for C
with the tree for G
at the head of the upstream branch. You'll compare "where they were" with "where they ended up", regardless of any intermediate points they visited on perhaps an arbitrarily long drive. :-) For instance, if commit F
adds a file this/that
and then commit G
removes it again, you won't see the file.
git diff --stat master origin/master
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With