Rebasing is the operation to get the others work rewriting YOUR commits on
top of them, it means you will never rewrite their history.
That deserves a better explanation, actually, visually, it doesn't look like
to be rewritten but it is, and in the natural historical order.
Note, everything already pushed will be the exact same as it is on the
remote repo and your work will be re-writen on top, so the only risks is if
YOU have an unpushed merge, in this case YOUR merge will be flaten but if
you follow the guideline I explained in the previous post, it will never
happen.
Thanks,
-Fred
-----Message d'origine-----
From: Frédéric THOMAS
Sent: Friday, March 22, 2013 10:12 AM
To: dev@flex.apache.org
Subject: Re: [OT] Log history
Hi,
I'm happy you gone into this and less because I thought you already
understood why and when it is better and cleaner while it is safe to use
rebasing instead of merging but no problem, I'm going to try to explain it
again later.
1- Branching:
The point, in the example I provided was to illustrate how you should work
from a branch as branching and merging are cheap and are considered as a
standard developement workflow on Git, even if you work only on local
branches, the reason behind that is that you might discover another bug,
nothing relative to the one you're working on (but that impact the same
file(s)) and this new bug has a higher priority and then has to be fixed
now, making you stoping the dev of your current bug.
It's then better to fix it on another branch, doing do, it will be
availlable for the others as well as for you if you rebase your branch on it
(again, I will tell you later why it is safe to do so at this point).
If you have been working on the develop branch directly or on the branch
dedicated to the bug you was working on before, it would have not been clear
later in the paralelle history line of your bugfix why there's something not
relative to it, I made an example of this you can look at [1], as you will
see, there's nothing destructive using pull --rebase as soon as you
understand when, where and why to use it.
I hope with the last paragraph, I made clearer why working on a
feature/bugfix branch is better than on the develop branch.
Indeed, if you work with someone else, it makes the thing more obvious.
Note: If you apply a quick patch or the dev is only one line of code to
change and there are no tests to do, etc..., in this case, it's ok to do it
directly on the develop branch, taking the precaution of rebasing before
committing however.
2- Rebasing, merging, what, when, where and why :
Know something once and for ever: rebasing preserve a good history and is
not destructive until you didn't merge the branch you are working on and
didn't pushed it yet.
(and for the latter, you can always avoid it as soon as you follow the good
practices, see the conclusion).
Note, I explain with my words and my poor English :P
Let's start:
A- Rebasing:
a- What is rebasing:
Rebasing is the operation to get the others work rewriting YOUR commits on
top of them, it means you will never rewrite their history.
b- When rebasing:
Each time you know or you thing the branch you're based on changed or even
only when there is a significant amount of time you didn't do it.
c- Where and from where to rebase:
From a branch: it means everywhere.
The From Where is depending if you are working on a local branch or a
tracked branch.
From a local branch, you will like to rebase onto the branch your branch is
based from.
From a tracked branch, same as before plus the same remote branch to track
what your mates did.
d- Finaly, WHY it works and it is not descrutive unless you don't follow the
good practice i'm explaining in this doc :
Because until you didn't merge and not pushed, there are no cases where
rebase will not preserve yours and the others history, it will put your work
on top of the others, if you/they did a merge and pushed it, this merge
still will be preserved.
B- Merging:
a- What is merging:
Merging is the operation to of joining 2 or more developement lines,
basicly, this operation will write your commits ahead of the current HEAD,
you can use the --no-ff flag to indicate you want an extra commit, the merge
commit, which will make your work easily reversed and will identify clearly
this work on the remote branch it will be pushed.
b- When merging:
Just before pushing, like that, you are preversed from the mad reads I see
on internet talking about the rebase risks.
c- Where merging:
From the branch you want your feature/bugfix branch be merge.
d- Why merging :
I mean, the anwser is in the What.
C- Conclusion:
Reabase all the time, until you don't have a pending merge that is not
pushed.
But if you follow my guideline relative to the When merging, you should not
encounter this situation.
I hope those explanations anwser all of your questions, except maybe this
one:
U:\gitLab\work\asf\flex\testWorkFlow\justin>git reset --hard 54072f3
How do I know I need to do this? Would I need to do this every time?
I really don't want to have to work though obscure git options and issue a
dozen git commands just to check in a single fix to a single file. If we
have to do that then I think we are using the tools incorrectly or it's the
wrong tool for the job. IMO we need to make it as easy or easier than SVN to
use and add yet more complexity.
In the context of the demo I did, it was to revert the timeline just before
the merge operation which did a no fast forward merge with the --no-ff flag,
causing the creation of a merge commit, I wanted to show you how to remove
it in case you decided you wanted a flat history at the end.
Thanks,
-Fred
[1]
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git checkout -b bug2fix1
Switched to a new branch 'bug2fix1'
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ ls bug2fixDir/
bug2FixFile1 bug2FixFile2
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ cat bug2fixDir/bug2FixFile1
This is the 1rst line
this is the 2nd line
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ echo Bug2fix1 should fix the line1 writing first instead of 1rst > null
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ cat bug2fixDir/bug2FixFile1
This is the first line
this is the 2nd line
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git commit -m "bug2fix1: Fixed bub2fixFile1" bug2fixDir/bug2FixFile1
[bug2fix1 51af745] bug2fix1: Fixed bub2fixFile1
1 file changed, 1 insertion(+), 1 deletion(-)
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ echo As you can see, there is the second line to fix as well but not plan
for this bug, so I open an other jira and f
ix it > nul
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git checkout develop
Switched to branch 'develop'
Your branch is ahead of 'origin/develop' by 2 commits.
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git checkout -b bug2fix2
Switched to a new branch 'bug2fix2'
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix2)
$ cat bug2fixDir/bug2FixFile1
This is the 1rst line
this is the 2nd line
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix2)
$ echo Fix the line 2 > nul
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix2)
$ cat bug2fixDir/bug2FixFile1
This is the 1rst line
this is the second line
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix2)
$ git commit -m "bug2fix2: Fixed bug2fixFile1" bug2fixDir/bug2FixFile1
[bug2fix2 46f7fe0] bug2fix2: Fixed bug2fixFile1
1 file changed, 1 insertion(+), 1 deletion(-)
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix2)
$ git checkout develop
Switched to branch 'develop'
Your branch is ahead of 'origin/develop' by 2 commits.
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git merge --no-ff bug2fix2
Merge made by the 'recursive' strategy.
bug2fixDir/bug2FixFile1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git branch -d bug2fix2
Deleted branch bug2fix2 (was 46f7fe0).
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git push
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (13/13), 1.16 KiB, done.
Total 13 (delta 3), reused 0 (delta 0)
To U:/gitLab/work/asf/flex/testWorkFlow/..\flex-sdk.git
3cbafc4..3830e37 develop -> develop
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git checkout bug2fix1
Switched to branch 'bug2fix1'
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git pull --rebase origin develop
From U:/gitLab/work/asf/flex/testWorkFlow/..\flex-sdk
* branch develop -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Applying: bug2fix1: Fixed bub2fixFile1
Using index info to reconstruct a base tree...
M bug2fixDir/bug2FixFile1
Falling back to patching base and 3-way merge...
Auto-merging bug2fixDir/bug2FixFile1
CONFLICT (content): Merge conflict in bug2fixDir/bug2FixFile1
Failed to merge in the changes.
Patch failed at 0001 bug2fix1: Fixed bub2fixFile1
The copy of the patch that failed is found in:
u:/gitLab/work/asf/flex/testWorkFlow/justin/.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git
rebase --abort".
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin
((3830e37...)|REBASE)
$ git mergetool bug2fixDir/bug2FixFile1
Merging:
bug2fixDir/bug2FixFile1
Normal merge conflict for 'bug2fixDir/bug2FixFile1':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (p4merge):
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin
((3830e37...)|REBASE)
$ cat bug2fixDir/bug2FixFile1
This is the first line
this is the second line
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin
((3830e37...)|REBASE)
$ echo it was a normal confict, I resolved it now, I am going to fix the
last file > nul
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin
((3830e37...)|REBASE)
$ git rebase --continue
Applying: bug2fix1: Fixed bub2fixFile1
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ echo Fixed this file > bug2fixDir/bug2FixFile2
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ cat bug2fixDir/bug2FixFile2
Fixed this file
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git status
# On branch bug2fix1
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working
directory)
#
# modified: bug2fixDir/bug2FixFile2
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# bug2fixDir/bug2FixFile1.orig
no changes added to commit (use "git add" and/or "git commit -a")
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ rm bug2fixDir/bug2FixFile1.orig
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git status
# On branch bug2fix1
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working
directory)
#
# modified: bug2fixDir/bug2FixFile2
#
no changes added to commit (use "git add" and/or "git commit -a")
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git commit -m "bug2fix1: Fixed bug2fixFile2" bug2fixDir/bug2FixFile2
1 file changed, 1 insertion(+)
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (bug2fix1)
$ git checkout develop
Switched to branch 'develop'
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git merge --no-ff bug2fix1
Merge made by the 'recursive' strategy.
bug2fixDir/bug2FixFile1 | 4 ++--
bug2fixDir/bug2FixFile2 | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
AsusFred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git branch -d bug2fix1
Deleted branch bug2fix1 (was 96c462c).
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git push
Counting objects: 13, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 857 bytes, done.
Total 9 (delta 3), reused 0 (delta 0)
To U:/gitLab/work/asf/flex/testWorkFlow/..\flex-sdk.git
3830e37..aa030f4 develop -> develop
Fred@ASUSFRED-PC /u/gitLab/work/asf/flex/testWorkFlow/justin (develop)
$ git hist
* aa030f4 2013-03-22 | Merge branch 'bug2fix1' into develop (HEAD,
origin/develop, develop) [Justin Mclean]
|\
| * 96c462c 2013-03-22 | bug2fix1: Fixed bug2fixFile2 (bug2fix1) [Justin
Mclean]
| * b931b4e 2013-03-22 | bug2fix1: Fixed bub2fixFile1 [Justin Mclean]
|/
* 3830e37 2013-03-22 | Merge branch 'bug2fix2' into develop [Justin
Mclean]
|\
| * 46f7fe0 2013-03-22 | bug2fix2: Fixed bug2fixFile1 [Justin Mclean]
|/
* fcb51d5 2013-03-22 | Renamed the file [Justin Mclean]
* 868fa15 2013-03-22 | prepared the bug2fix demo1 [Justin Mclean]
* 3cbafc4 2013-03-21 | Added fr_FR [Justin]
* c3058e9 2013-03-21 | Updated the README again [Frédéric THOMAS]
* 54072f3 2013-03-21 | Added pt_PT [Justin Mclean]
* f43029d 2013-03-21 | Updated the README [Frédéric THOMAS]
* 1032fa2 2013-03-21 | Added README (origin/release, origin/master,
origin/HEAD, master) [Frédéric THOMAS]
-- NOTHING DESTRUCTIVE, both of the bug histories have been preserved and
are clearly visible, for this demo, I didn't flaten the bug2fix2 to the
develop branch even though it has one commit, I would have done it in the
real live.
-----Message d'origine-----
From: Justin Mclean
Sent: Friday, March 22, 2013 2:56 AM
To: dev@flex.apache.org
Subject: Re: [OT] Log history
Hi,
Thanks for going though that.
---------------------------------
You add locales
---------------------------------
U:\gitLab\work\asf\flex\testWorkFlow\justin>git checkout -b
test_Rebased_Hotfix_Without_Conflic
Switched to a new branch 'test_Rebased_Hotfix_Without_Conflic'
etc etc
Actually it wasn't quite like that in that as files and directories already
existed. It does seem a bit excessive to make a branch just to change a
single file and it also assumes I have no other changes and a perfectly
clean tree (not the case). As the branch is local and not shared with anyone
else do you really need a branch for a simple change to a singe file?
U:\gitLab\work\asf\flex\testWorkFlow\justin>git pull --rebase origin
develop
This is the bit I'm confused about why would I use --rebase when all
documentation I've read say it dangerous to use and it hard to undo (unlike
merge) and it difficult to see what it's going to do (no --dry-run) - I know
both of this situations have work arounds (mostly) but they are complex. It
seems to me that knowing what about to happen and being able to back out of
it if things go wrong is far more important than having a totally "clean"
history. It's not like the history produced was incorrect or even confusing.
U:\gitLab\work\asf\flex\testWorkFlow\justin>git merge --no-ff
test_Rebased_Hotfix_Without_Conflic
Why is --no-ff required? What would happen if this option wasn't used in
this case? And if I didn't make the branch in the first place there would be
no need for this merge or the hard reset below right?
U:\gitLab\work\asf\flex\testWorkFlow\justin>git reset --hard 54072f3
How do I know I need to do this? Would I need to do this every time?
I really don't want to have to work though obscure git options and issue a
dozen git commands just to check in a single fix to a single file. If we
have to do that then I think we are using the tools incorrectly or it's the
wrong tool for the job. IMO we need to make it as easy or easier than SVN to
use and add yet more complexity.
Thanks,
Justin