Git/Workflow/Stage: Difference between revisions
(10 intermediate revisions by 2 users not shown) | |||
Line 11: | Line 11: | ||
==Initial Setup== | ==Initial Setup== | ||
Add a remote called "<code>stage</code>" to refer to the topic stage: | Add a remote called "<code>stage</code>" to refer to the topic stage. | ||
In general the stage for some upstream repository <code>''repo''.git</code> is <code>stage/''repo''.git</code>: | |||
$ git remote add stage git://public.kitware.com/stage/''repo''.git | $ git remote add stage git://public.kitware.com/stage/''repo''.git | ||
Line 24: | Line 25: | ||
==Staging a Topic== | ==Staging a Topic== | ||
{| | {| style="width: 100%" cellspacing="0" cellpadding="0" | ||
!width=30%|Actions | !width=30%|Actions | ||
!width=30%|Results | !width=30%|Results | ||
Line 48: | Line 49: | ||
|colspan="2"| | |colspan="2"| | ||
When the topic is ready for publication push it to the stage. | When the topic is ready for publication push it to the stage. | ||
Fetch from the stage just before pushing to help git compute a minimal set of objects to push. | |||
Pushing <code>HEAD</code> will automatically use the ''topic-name'': | Pushing <code>HEAD</code> will automatically use the ''topic-name'': | ||
|- | |- | ||
Line 53: | Line 55: | ||
:{| | :{| | ||
| | | | ||
$ git fetch stage --prune | |||
$ git push stage HEAD | $ git push stage HEAD | ||
To git@public.kitware.com:stage/''repo''.git | To git@public.kitware.com:stage/''repo''.git | ||
Line 65: | Line 68: | ||
==Viewing all Topics== | ==Viewing all Topics== | ||
{| | {| style="width: 100%" cellspacing="0" cellpadding="0" | ||
!width=30%|Actions | !width=30%|Actions | ||
!width=30%|Results | !width=30%|Results | ||
Line 112: | Line 115: | ||
==Merging a Topic== | ==Merging a Topic== | ||
{| | {| style="width: 100%" cellspacing="0" cellpadding="0" | ||
!width=30%|Actions | !width=30%|Actions | ||
!width=30%|Results | !width=30%|Results | ||
Line 120: | Line 123: | ||
Tell the stage to merge the topic into '''next'''. | Tell the stage to merge the topic into '''next'''. | ||
It automatically computes a merge commit based on the latest upstream '''next'''. | It automatically computes a merge commit based on the latest upstream '''next'''. | ||
If merging fails with conflicts the stage will print instructions. | |||
|- | |- | ||
| | | | ||
Line 151: | Line 155: | ||
. \ \ | . \ \ | ||
........o----o stage/next | ........o----o stage/next | ||
|} | |||
==Updating a Topic== | |||
Perhaps after merging to '''next''' you discover that an additional change is needed. | |||
{| style="width: 100%" cellspacing="0" cellpadding="0" | |||
!width=30%|Actions | |||
!width=30%|Results | |||
!Troubleshooting | |||
|- | |||
|colspan="2"| | |||
Since the merge was done by the topic stage repository we never switched branches locally. | |||
Just continue development: | |||
|- | |||
| | |||
:<code>$ edit files</code><br> | |||
:<code>$ git commit</code><br> | |||
| | |||
...o----o master | |||
\ | |||
o----o----o *'''''topic-name''''' | |||
^ stage/''topic-name'' | |||
|- | |||
|colspan="2"| | |||
Push the topic to the stage. | |||
|- | |||
| | |||
:{| | |||
| | |||
$ git fetch stage | |||
$ git push stage HEAD | |||
To git@public.kitware.com:stage/''repo''.git | |||
171b457..27c71e8 HEAD -> ''topic-name'' | |||
|} | |||
| | |||
...o----o master | |||
\ | |||
o----o----o *'''''topic-name''''', stage/''topic-name'' | |||
|- | |||
|colspan="2"| | |||
The stage's reference to the topic will fast-forward. | |||
We can see that the topic head is no longer reachable from '''next''': | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' print | |||
... | ... | |||
''topic-name'' | master=0 next=0 | |||
''other-topic'' | master=0 next=1 | |||
... | ... | |||
|} | |||
| | |||
...o----o stage/master | |||
. \ \ | |||
. \ o----o----o stage/''topic-name'' | |||
. \ \ | |||
. o----o \ stage/''other-topic'' | |||
. \ \ | |||
........o----o stage/next | |||
|- | |||
|colspan="2"| | |||
Merge the topic into '''next''' again: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' merge -b next ''topic-name'' | |||
Fetching upstream next | |||
Merge branch ''topic-name'' | |||
Pushing upstream next | |||
To ../../''repo''.git | |||
|} | |||
|- | |||
|colspan="2"| | |||
Now '''next''' can see the whole topic again: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' print | |||
... | ... | |||
''topic-name'' | master=0 next=1 | |||
''other-topic'' | master=0 next=1 | |||
... | ... | |||
|} | |||
| | |||
...o----o stage/master | |||
. \ \ | |||
. \ o----o----o stage/''topic-name'' | |||
. \ \ \ | |||
. o----o \ \ stage/''other-topic'' | |||
. \ \ \ | |||
........o----o----o stage/next | |||
|} | |||
==Finishing a Topic== | |||
After development of the topic has been finished and it is considered stable. | |||
{| style="width: 100%" cellspacing="0" cellpadding="0" | |||
!width=30%|Actions | |||
!width=30%|Results | |||
!Troubleshooting | |||
|- | |||
|colspan="2"| | |||
Merge it to master: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' merge -b master ''topic-name'' | |||
Fetching upstream master | |||
Merge branch ''topic-name'' | |||
Pushing upstream master | |||
To ../../''repo''.git | |||
Deleting fully merged topic ''topic-name'' (27c71e8) from stage. | |||
|} | |||
|- | |||
|colspan="2"| | |||
The "Deleting ..." line occurs when the topic is reachable from all integration branches. | |||
Fear not, the deletion is safe even during a race condition when someone else updates it with a new commit at the same time as your merge completes. | |||
The stage no longer references the topic explicitly: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' print | |||
... | ... | |||
''other-topic'' | master=0 next=1 | |||
... | ... | |||
|} | |||
| | |||
...o----o-------------o stage/master | |||
. \ \ / | |||
. \ o----o----o | |||
. \ \ \ | |||
. o----o \ \ stage/''other-topic'' | |||
. \ \ \ | |||
........o----o----o stage/next | |||
|} | |||
==Abandoning a Topic== | |||
Sometimes a topic proves to be unusable and should never be merged to master. | |||
{| style="width: 100%" cellspacing="0" cellpadding="0" | |||
!width=30%|Actions | |||
!width=30%|Results | |||
!Troubleshooting | |||
|- | |||
|colspan="2"| | |||
Add a commit to the topic that reverts all its changes, such as using git revert. | |||
|- | |||
| | |||
:<code>$ git revert -n origin/master..HEAD</code><br> | |||
:''(If the topic has merges this may not work. Ask on the project mailing list.)'' | |||
:<code>$ git commit</code><br> | |||
| | |||
...o----o master | |||
\ | |||
o----o----o----o *'''''topic-name''''' | |||
^ stage/''topic-name'' | |||
|- | |||
|colspan="2"| | |||
Push the topic to the stage. | |||
|- | |||
| | |||
:{| | |||
| | |||
$ git push stage HEAD | |||
To git@public.kitware.com:stage/''repo''.git | |||
27c71e8..7892e6b HEAD -> ''topic-name'' | |||
|} | |||
| | |||
...o----o master | |||
\ | |||
o----o----o----o *'''''topic-name''''', stage/''topic-name'' | |||
|- | |||
|colspan="2"| | |||
Merge the topic into '''next''' again: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' merge -b next ''topic-name'' | |||
Fetching upstream next | |||
Merge branch ''topic-name'' | |||
Pushing upstream next | |||
To ../../''repo''.git | |||
|} | |||
|- | |||
|colspan="2"| | |||
Now '''next''' can see the whole topic but none of its changes: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' print | |||
... | ... | |||
''topic-name'' | master=0 next=1 | |||
''other-topic'' | master=0 next=1 | |||
... | ... | |||
|} | |||
| | |||
...o----o stage/master | |||
. \ \ | |||
. \ o----o----o----o stage/''topic-name'' | |||
. \ \ \ \ | |||
. o----o \ \ \ stage/''other-topic'' | |||
. \ \ \ \ | |||
........o----o----o----o stage/next | |||
|- | |||
|colspan="2"| | |||
Finally, push an empty ref to the stage to delete the topic: | |||
|- | |||
| | |||
:<code>$ git push stage :''topic-name''</code><br> | |||
|- | |||
|colspan="2"| | |||
The stage no longer references the topic explicitly: | |||
|- | |||
| | |||
:{| | |||
| | |||
$ ssh git@public.kitware.com stage ''repo'' print | |||
... | ... | |||
''other-topic'' | master=0 next=1 | |||
... | ... | |||
|} | |||
| | |||
...o----o stage/master | |||
. \ \ | |||
. \ o----o----o----o | |||
. \ \ \ \ | |||
. o----o \ \ \ stage/''other-topic'' | |||
. \ \ \ \ | |||
........o----o----o----o stage/next | |||
|} | |} |
Revision as of 18:14, 14 December 2011
Introduction
Our Topic Stage repositories provide a central staging area for topic branches under development. Unlike an official repository a topic stage may have any number of branches. Developers are free to create, update, and delete topics in the stage through Git's ssh protocol.
Tutorial
Initial Setup
Add a remote called "stage
" to refer to the topic stage.
In general the stage for some upstream repository repo.git
is stage/repo.git
:
$ git remote add stage git://public.kitware.com/stage/repo.git $ git config remote.stage.pushurl git@public.kitware.com:stage/repo.git
One may fetch from the stage at any time:
$ git fetch stage --prune
Use the "--prune
" option to remove local references to remote topic branches that have been deleted.
Staging a Topic
Actions | Results | Troubleshooting |
---|---|---|
Create a local topic branch and develop on it. Here we use the placeholder topic-name for the branch name. | ||
...o----o master, ^ *topic-name | ||
...o----o master \ o----o *topic-name | ||
When the topic is ready for publication push it to the stage.
Fetch from the stage just before pushing to help git compute a minimal set of objects to push.
Pushing | ||
|
...o----o master, stage/master \ o----o *topic-name, stage/topic-name |
Viewing all Topics
Actions | Results | Troubleshooting | |
---|---|---|---|
Print the current stage topic table: | |||
|
...o----o stage/master . \ \ . \ o----o stage/topic-name . \ . o----o stage/other-topic . \ ........o stage/next | ||
Each row represents one topic. The first column names the topic, the rest name each integration branch with a 0 or 1 indicating whether it can reach the topic. | |||
One may also get machine-readable output:
|
Merging a Topic
Actions | Results | Troubleshooting |
---|---|---|
Tell the stage to merge the topic into next. It automatically computes a merge commit based on the latest upstream next. If merging fails with conflicts the stage will print instructions. | ||
| ||
Print the new state of the stage: | ||
|
...o----o stage/master . \ \ . \ o----o stage/topic-name . \ \ . o----o \ stage/other-topic . \ \ ........o----o stage/next |
Updating a Topic
Perhaps after merging to next you discover that an additional change is needed.
Actions | Results | Troubleshooting |
---|---|---|
Since the merge was done by the topic stage repository we never switched branches locally. Just continue development: | ||
|
...o----o master \ o----o----o *topic-name ^ stage/topic-name | |
Push the topic to the stage. | ||
|
...o----o master \ o----o----o *topic-name, stage/topic-name | |
The stage's reference to the topic will fast-forward. We can see that the topic head is no longer reachable from next: | ||
|
...o----o stage/master . \ \ . \ o----o----o stage/topic-name . \ \ . o----o \ stage/other-topic . \ \ ........o----o stage/next | |
Merge the topic into next again: | ||
| ||
Now next can see the whole topic again: | ||
|
...o----o stage/master . \ \ . \ o----o----o stage/topic-name . \ \ \ . o----o \ \ stage/other-topic . \ \ \ ........o----o----o stage/next |
Finishing a Topic
After development of the topic has been finished and it is considered stable.
Actions | Results | Troubleshooting |
---|---|---|
Merge it to master: | ||
| ||
The "Deleting ..." line occurs when the topic is reachable from all integration branches. Fear not, the deletion is safe even during a race condition when someone else updates it with a new commit at the same time as your merge completes. The stage no longer references the topic explicitly: | ||
|
...o----o-------------o stage/master . \ \ / . \ o----o----o . \ \ \ . o----o \ \ stage/other-topic . \ \ \ ........o----o----o stage/next |
Abandoning a Topic
Sometimes a topic proves to be unusable and should never be merged to master.
Actions | Results | Troubleshooting |
---|---|---|
Add a commit to the topic that reverts all its changes, such as using git revert. | ||
|
...o----o master \ o----o----o----o *topic-name ^ stage/topic-name | |
Push the topic to the stage. | ||
|
...o----o master \ o----o----o----o *topic-name, stage/topic-name | |
Merge the topic into next again: | ||
| ||
Now next can see the whole topic but none of its changes: | ||
|
...o----o stage/master . \ \ . \ o----o----o----o stage/topic-name . \ \ \ \ . o----o \ \ \ stage/other-topic . \ \ \ \ ........o----o----o----o stage/next | |
Finally, push an empty ref to the stage to delete the topic: | ||
| ||
The stage no longer references the topic explicitly: | ||
|
...o----o stage/master . \ \ . \ o----o----o----o . \ \ \ \ . o----o \ \ \ stage/other-topic . \ \ \ \ ........o----o----o----o stage/next |