Create an initial repository following the instructions below.
initial_repo.sh
#!/usr/bin/env sh
git init
# first commit
echo "initial repo" > initial.txt && git add initial.txt && git commit -m "initial repo"
# new branch
git checkout -b new-feature
echo "file a" > a.txt && git add a.txt && git commit -m "commit a"
echo "file b" > b.txt && git add b.txt && git commit -m "commit b"
echo "file c" > c.txt && git add c.txt && git commit -m "commit c"
Executing the script above, you will have a git structure like this one:
$ git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all
* f7f8e5d - (HEAD -> new-feature) commit c (3 seconds ago) <Augusto Morais>
* 52db9e3 - commit b (3 seconds ago) <Augusto Morais>
* c4244c9 - commit a (3 seconds ago) <Augusto Morais>
* 2b19e95 - (master) initial repo (3 seconds ago) <Augusto Morais>
Fast Forward is the default option for git merge
So, merging new-feature
into master
you will be this:
$ git checkout master
$ git merge
* f7f8e5d - (HEAD -> master, new-feature) commit c (3 minutes ago) <Augusto Morais>
* 52db9e3 - commit b (3 minutes ago) <Augusto Morais>
* c4244c9 - commit a (3 minutes ago) <Augusto Morais>
* 2b19e95 - initial repo (3 minutes ago) <Augusto Morais>
No Fast Forward is not enabled by default and you have to pass this option to git merge
command
So, merging new-feature
into master
you will be this:
$ git checkout master
$ git merge --no-ff -m "added new feature"
* f7f8e5d - (HEAD -> master, new-feature) commit c (3 minutes ago) <Augusto Morais>
* 52db9e3 - commit b (3 minutes ago) <Augusto Morais>
* c4244c9 - commit a (3 minutes ago) <Augusto Morais>
* 2b19e95 - initial repo (3 minutes ago) <Augusto Morais>
$ git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all
* f7f8e5d - (HEAD -> master, new-feature) commit c (12 minutes ago) <Augusto Morais>
* 52db9e3 - commit b (12 minutes ago) <Augusto Morais>
* c4244c9 - commit a (12 minutes ago) <Augusto Morais>
* 2b19e95 - initial repo (12 minutes ago) <Augusto Morais>
$ git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all
* 0acabeb - (HEAD -> master) new-feature (14 seconds ago) <Augusto Morais>
|\
| * 389934e - (new-feature) commit 3 (20 minutes ago) <Augusto Morais>
| * 3dacbaf - commit 2 (20 minutes ago) <Augusto Morais>
| * 4d403b2 - commit 1 (20 minutes ago) <Augusto Morais>
|/
* a00eb72 - initial repo (20 minutes ago) <Augusto Morais>
The biggest difference between each strategy is the way that you will organize your history. As you can see, --no-ff
creates an extra commit with "new-feature". Thus, you can easily check what is going on in your history and remove a new feature, e.g.:
git rebase -i 0acabeb~
this command will automatically get all commits from the new-feature
.
Of course, you can remove a feature using thefast-forward
strategy but for that, you need to pick up each commit individually and this can be a bit annoying.
git rebase -i f7f8e5d~3
note: ~3
refers to the last 3 commits including the f7f8e5d