On Nov 2, 2007, at 11:44 AM, Junio C Hamano wrote:
Steffen Prohaska <prohaska@xxxxxx> writes:
- in a workflow that is base on shared branches (CVS-style),
...
In addition push should push back to the remote branch a local
topic was originally branched off.
Why? If it is shared, and if you are shooting for the simplest
set of commands, wouldn't you work this way?
Yes. I would work exactly this way with current git.
$ git clone $public my-work-dir
$ cd my-work-dir
$ git checkout -b --track foo origin/foo
So the implicit rule here is
"name a branch identical in all repositories you're dealing with"
right?
That is foo is named foo at the remote, named foo as a tracking
branch (git handles this automatically) and is named foo as your
local branch.
I believe it is reasonable. Though I have two questions:
1) If this is best practice, why doesn't save git me from typos?
Why do I need to type "foo" correctly twice?
2) What shall I do if I am dealing with more than one shared
repository? Andreas' group should already run into problems
here. They have several shared repos and if they want to
checkout several local branches from different repos they
need to somehow encode the name of the remote in the name
of the local branch.
$ hack hack hack, commit, commit, commit *on* *foo*
$ git push $public foo
I think the recent git defaults to --track anyway so the third
step do not spell out --track.
It does.
With your "remote.$public.push = HEAD", the last step would be
"git push" without any parameter.
Indeed. Or with my "branch.$name.push" it would just be "git push"
as well. And I'd be probably happy then.
If you do use private topics, then the story would change this
way:
$ git checkout -b --track foo origin/foo
$ git checkout -b topic1 foo ;# or origin/foo
I'd be more happy without 'or'. I really want to give a single
recommendation.
So the question here is: Should I branch off the local branch or
should I branch off the remote branch? When should I do what?
What is best practice and what is used for 'exceptional'
situations?
$ hack hack hack, commit, commit, commit on topic1
$ git checkout -b topic2 foo ;# or origin/foo
$ hack hack hack, commit, commit, commit on topic2
$ git checkout foo
$ git merge topic1
$ test test test; # test _your_ changes
$ git merge topic2
$ test test test; # test _your_ changes
$ git push ;# again push 'foo' out
This focuses testing on the integration of topic1 with topic2.
You could as well do the following
$ git checkout -b topic1 origin/foo
$ hack ...
$ git checkout -b topic2 origin/foo
$ hack ..
[ later ]
$ git checkout topic1
$ git pull # or git fetch; git rebase origin/foo
$ test test test
$ git push origin topic1:origin/foo
[ later ]
$ git checkout topic2
$ git pull # or git fetch; git rebase origin/foo
$ test test test
$ git push origin topic2:origin/foo
With my "branch.$name.push" it would just be "git push" here.
This workflow focuses testing on the integration of each of your
topics with the new changes on the shared branch independently
of your other topic.
You're done at this point. No need to merge a second time,
no need to reset branches.
It's probably a good idea to delete your local branches
now. And there is one minor question related to that: Where
to park your HEAD if you want to clean up _all_ of your local
branches because you have nothing left to do? Everything is
on the shared remote branch. The only thing you're interested
now is to checkout new changes from the shared branch if
interesting work was done by others.
This may fail to fast forward. You may at this time want to
"git fetch" first, rebase topic1 or topic2 that conflict with
the other side on top of updated origin/foo, rebuild foo and
push the result out, like this:
Or you could just pull
[ this continues Junio's example from above, you are on branch foo. ]
$ git pull
$ test test; # test of your integration of topic1, topic2
# with the new changes on the shared branch
$ git push
$ git fetch
$ git rebase origin/foo topic1
$ git branch -f foo origin/foo
Here is another interesting point.
Would you recommend "git branch -f foo origin/foo" over
"git checkout foo; git reset --hard origin/foo"? I think the
first command is safer because it doesn't throw away uncommitted
changes. However it fails if you are already on branch foo. Then it
says "fatal: Cannot force update the current branch.". It is not
very intuitive if I'd ask users to first leave the branch they
want to modify, only to be able to use "git branch". "git reset"
always lets you achieve your goal. (BTW, I don't recommend having
local changes while doing integration testing ... but who knows
maybe someone feels comfortable with it.)
$ git checkout foo
$ git merge topic1
$ git merge topic2
$ test test test
$ git push
Using rebase requires more commands than using pull, and more
intrusive commands like "branch -f" or "reset --hard" are involved.
That doesn't mean that you should not use rebase. But it certainly
needs more explanation.
Another related question is the following: After some time the
user decides that some help on topic1 would be appreciated and
another developer promises to help. So they agree to work on
a shared branch name topic1. The first developer starts with
$ git push origin topic1
From now on he _MUST NOT_ use rebase any longer! So starting
to work on the topic with a second developer completely changed
the best practice. From now no rebase is forbidden, which was
best practice before.
So the question for me is: do I want to teach developer a pull
or a rebase workflow first? Currently I believe pull will be
safer for them, better supported by git, and there will be
situations they must use pull. If the only nuisance are loops
in the history when viewing them in gitk, I'm happy to accept
this.
... This makes the need for
pushing to a branch named differently on the remote side more
likely than in a pull-oriented workflow,
So I do not understand this remark.
Yeah, I should have added some explanation here. I had Andreas'
200-local-branches and the topic1/topic2 example in mind that
does the integration against the shared branch.
Steffen
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html