I'm trying to merge two different branches, but git tells me that everything is up-to-date
I'm a git noob, and I know I'm missing something fundamental here. I've got three branches: master, feature1 and feature2. No two branch is identical, yet any attempt to merge from one branch to the other results in an "up-to-date" message. As you can imagine, I've done my work on feature1 and feature2, and now I just want to merge that work back into my master.
Here is what my current graph looks like:
* c719e79 master
|\
| * 3f38259 feature2
| * 4e2af8c
| * a6ee18c
| * 2339052
| * 2e31d49
| * 2586659
| * 8b4a194
| * 56200c1
| * 97598e3
| * c28bc8d
| * 68b2e2f
| * 1ad4ad8
| * 3d5f4ad
| * 83435ca
| * 4049428
| * 581134a
| * 6e5aa2d
* | 2c88093
|/
* 3130ec9 feature1
* 54a5311 INITIAL COMMIT
Any ideas?
UPDATE
VonC - the explanation makes sense, but my git repo still doesn't. When I switch over to my master branch and then run "$ git diff --stat feature2", I get the following output:
$git 开发者_JAVA技巧diff --stat feature2
File1 | 2 +-
File2 | 6 +++---
File3 | 4 ++--
File4 | 2 +-
File5 | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)
I get an even longer list of files if I run the same command for feature1. So... I still have it telling me that I'm up-to-date, but the files in each branch are different.
UPDATE 2
@Scott - Okay, I think your response has helped clarify my problem a little. I understand that merging will not make all the branches identical, but will simply update the branch that I'm on.
However, it appears that my commits have gotten "out of order", or something. In other words, there are changes that exist on the feature2 branch that I want to appear on my master branch. Git must think that version of the files on my master branch are the "right" ones (whatever that means). How do I get Git to commit the differences on feature2 branch to my master branch when it thinks that the changes currently on master are the latest and greatest?
UPDATE 3 (final)
Well, I'm very grateful to all of you who tried to help me out. I figured out a work-around that solved it just as well, but I never actually figured out how to do what I had in mind.
After thinking through some of your comments, I did a rebase. The graph of the commit history was a straight line like you would expect. The trouble didn't go away, though: my feature2 branch was behind master by one commit, but it contained code that actually made it the branch with the "latest and greatest" code. Trying to merge the branches did nothing. Finally, I just decided to create a new branch off of my feature2 branch and called that "latest". So I guess, in the end, I'm grateful for how easy it is to branch with git. But it's clear that I'm missing something...
Thanks again, everyone.
The "Already up-to-date" does mean that one branch in ancestor of the other, all changes from one branch being already in the other.
From the git merge
man page:
If all named commits are already ancestors of HEAD,
git merge
will exit early with the message "Already up-to-date."
Here the HEAD of feature1
is an ancestor of master
(master
has some new work made from feature1
HEAD).
So git merge feature1
will result in an "Already up-to-date" message.
As for feature2
, your graph log shows it has been merged at some point in master
.
Trying to redo the merge will also result in an "Already up-to-date".
The problem is that you are expecting the feature1 and feature2 branches to change as well as master when you merge them in. However, merging only effects the branch you are currently on. If you want all three branches to point to the same commit snapshot, you can run
$ git checkout feature1
$ git merge master
$ git checkout feature2
$ git merge master
That will update feature1 and then feature2 to where master is - and you won't get any merge conflicts, since they are both direct ancestors of master.
The important point is: when you merge a branch into another branch, it only modifies the branch you are on (the one you are merging into) not the branch that you are merging in. In other words, if you are currently on your 'master' branch and you merge in 'feature1', it updates 'master' but not 'feature1'.
While on branch master, I'm using git merge feature1 and git merge feature2
What happened was IMO a so-called FF(Fast-Forward)-Merge.
From the MAN-Page:
git merge definition:
git-merge - Join two or more development histories together
What has happened:
FAST-FORWARD MERGE
Often the current branch head is an ancestor of the named commit. This is the most common case especially > when invoked from git pull: you are tracking an upstream repository, you have committed no local changes, > and now you want to update to a newer upstream revision. In this case, a new commit is not needed to store > the combined history; instead, the HEAD (along with the index) is updated to point at the named commit, without creating an extra merge commit.
This behavior can be suppressed with the --no-ff option.
(Source-Link)
Excursion: Additional information about branches
As branches are nothing more than just pointers to commits AND feature1
/ feature2
are ancestors of master
(as mentioned before), there is no reason to 'copy' the commits (and therefore the commits' history). It's more performant to just re-point the master
-branch(-pointer) to the last commit.
Why is the master-branch-pointer then not on the 3f38259
commit?
I'm not quite sure here, but I think:
git merge feature1
has the auto-commit-option (explicit: --commit
) turned on per default. So a commit is created. Plus, there is the 2c88093
commit in the master
-branch, but not in the feature2
-branch, which avoids putting the master
-branch-pointer just to the 3f38259 feature2
commit to produce something like
3f38259 feature2 master(*)
If you would re-point your master
to the 3f38259
branch explicitly , you would 'lose' the 2c88093
commit in your history.
Are you in the 'master' branch when you do the merge command?
git checkout master
git merge feature1
git merge feature2
How do I get Git to commit the differences on feature2 branch to my master branch when it thinks that the changes currently on master are the latest and greatest?
maybe git rebase
is what you are looking for? Link
I did it the dirty way: checkout the branch you want to merge into master, copy the files to an external folder, checkout master, copy the files back in, add the files and commit them.
You could check out branch master
, make sure all your changes are committed, then try
git pull . feature1 feature2
But I'm not exactly a git expert myself, so I couldn't tell you with certainty what this will do. I mean, I know that it should merge feature1
and feature2
into master
, but I can't guarantee that it will merge them exactly the way you want.
I'd advise backing up the repository first, just in case. Although I suppose you could always git reset --hard HEAD^
afterwards if something goes wrong.
精彩评论