Reputation: 4042
Right now I have a develop
branch, and I create a new branch feature-keyboard
using git checkout -b feature-keyboard develop
as a new version. Right now I need to do changes to both branches. What I am doing right now is I do so: git checkout -b feature-ui-changes develop
and then add some changes commit them. then git checkout develop
and git merge --no-ff feature-ui-changes
. But if I do the same first checkout feature-keyboard
and then merge changes to feature-ui-changes
. It says conflict. And It's suppose to. But how do I update changes to both develop
and feature-keyboard
branches after I do some changes to the app?
Upvotes: 1
Views: 1564
Reputation: 25396
You can do the changes on one branch, commit them. Then switch to the other branch and cherry-pick your changes:
git cherry-pick <commit-hash>
Upvotes: 1
Reputation: 58667
If you find yourself needing to "double commit" numerous changes between two branches, then that is a sign that there is possibly something wrong with your process. Perhaps the code was branched prematurely.
Git has a nice workflow for creating a "topic" branch where you develop something, while keeping up with the changes from that topic's upstream. Namely, you can use git rebase
to rewrite the branch history, and migrate the changes to a newer version of upstream.
This saves you the pain of doing double commits, and also prevents you from forking two copies of each upstream commit.
$ git checkout -b topic
# ... hack, commit, hack, commit, ...
$ git checkout master
# ... pull, hack, commit, pull, ...
Now there is all kinds of new stuff on master
not reflected in topic
: changes you have made, plus possibly upstream changes pulled in from another repo. You'd like to return to the work on topic
, but have that work based on the new master
. That's what rebasing is about:
$ git checkout topic
$ git rebase master
Git will figure out the ancestor point between the current branch, topic
, and master
. It will take the topic
changes from that point, and cherry pick them on top of the current master
. The resulting picks will then be installed as the topic
branch. Thereby, the topic
branch is rewritten: it is replaced with a whole new version of that branch. (Along the way, you may have to resolve conflicts, of course.)
If you have two or more such topics, you can treat them independently: rebase each one of them as you return to it, keeping it up to date with the master changes.
The nice thing after rebasing is that after topic
is rebased, it contains the upstream branch (such as master
) as a suffix: it has exactly all the commits that are in master
, plus some new commits. At that point, you can do:
git checkout master
git reset --hard topic # fast-forward master to the topic
Now master
has all the topic
changes: in fact, master
and topic
point to the same commit object: they are identical. We can do this safely because master
doesn't have any commits which are not already in topic
, thanks to the recent rebase. So we are not throwing away anything from master
: it just jumps forward.
If master
does have some new commits, you can also do an "other-way rebase":
# on master
git rebase topic # same as git reset --hard topic if master has no new commits!
The new changes on master
are rewound, then the topic
changes are brought in, and the new changes are re-played (cherry picked) on top. It's a mirror image of rebasing topic
to master
: rebase
doesn't care which branch is the trunk and which is the topic.
However, if those new master
commits are public, you are writing public history by rebasing them over topic
changes. You can get away with this if all the new master
commits not on topic
are your own and unpublished (you made them locally and haven't git push
-ed them to another repo), or you have some other justification for rewriting master
history even if it is published.
Upvotes: 1