A---B master \ C---D featureWe want the feature branch to be up-to-date with master.
command | merge | rebase |
---|---|---|
result |
A---B master \ C-B-D-E feature |
A---B master \ C'-D' feature |
pros |
|
|
cons |
|
|
merge vs rebasequestion is mostly context-dependent
---o---o---o master
---o---o---o---o---o---o master \ o---o---o feature
---o---o---o---o---o---o master feature_squash \ o---o---o feature
merge squashmy feature branch into the
squashbranch :
Squash commit -- not updating HEAD Automatic merge went well; stopped before committing as requested
---o---o---o---o--o---o master \ \ \ o feature_squash \ / o--o---o feature
squashbranch into master :
---o---o---o---o--o---o---o master feature_squash \ \ / \ o \ / o--o---o feature
squashbranch :
---o---o---o---o--o---o---o master \ \ / \ o \ / o--o---o feature
The title of this article as well as the solution below refer to master because it's a pretty common situation, but you can —of course— apply this to any branch .
cat << 'EOF' > .git/hooks/pre-commit #!/usr/bin/env bash currentBranch="$(git rev-parse --abbrev-ref HEAD)" if [ "$currentBranch" == 'master' ]; then echo 'None shall pass!' exit 1 fi EOF chmod +x .git/hooks/pre-commit
#!/usr/bin/env bash
currentBranch="$(git rev-parse --abbrev-ref HEAD)"
if [ "$currentBranch" == 'master' -a "$c2m" != 'yes' ]; then
echo 'None shall pass!'
exit 1
fi
F-------G myBranch / A---B---C---D---E master
F-------G myBranch / \ A---B---C---D---E---H master
A---B---C---D---E---H master myBranch
Branch branch set up to track remote branch branch from remote. Switched to a new branch 'branch'This :
fatal: Cannot update paths and switch to branch 'branch' at the same time. Did you intend to checkout 'myLocalBranch' which can not be resolved as commit?
Branch localBranch set up to track remote branch branch from remote.
Branch currentLocalBranch set up to track remote branch branch from remote.
This typically happens when you've committed on master, then realized that those commits better suit a feature branch. In other words, how may I go from this :
A---B---C---D---E master
to this :
C---D---E newBranch / A---B master
Before going further, make sure you have no uncommitted changes left.
git branch newBranch # Create a new branch, saving the desired commits git reset --hard HEAD~3 # Move master back by 3 commits (GONE from master) git checkout newBranch # Go to the new branch that still has the desired commits NB : instead of resetting to a nb of commits, you can reset until a specific commit ID : git reset --hard a1b2c3d4
You want to go back to C, and move D and E to the new branch. Here's what it looks like at first: A-B-C-D-E (HEAD) ↑ master After git branch newBranch: newBranch ↓ A-B-C-D-E (HEAD) ↑ master After git reset --hard HEAD~2: newBranch ↓ A-B-C-D-E (HEAD) ↑ master Since a branch is just a pointer, master pointed to the last commit. When you made newBranch, you simply made a new pointer to the last commit. Then using git reset you moved the master pointer back two commits. But since you didn't move newBranch, it still points to the commit it originally did.
NB : if you checkout newBranch from the existing master branch it ALREADY has those three commits included in it, so there's no use in picking them. At the end of the day to get what the OP wanted, you'll still have to do some form of reset --hard HEAD. https://stackoverflow.com/questions/1628563/move-the-most-recent-commits-to-a-new-branch-with-git#comment-36690393 Step 1 - Note which commits from master you want on a new branch : git checkout master git log Note the hashes of (say 3) commits you want on newBranch. Here I shall use: C commit: 9aa1233 D commit: 453ac3d E commit: 612ecb3 Note: You can use the first seven characters or the whole commit hash Step 2 - Put them on the new branch git checkout newBranch git cherry-pick 612ecb3 git cherry-pick 453ac3d git cherry-pick 9aa1233 NB : the order is important. You want to do the oldest commits first