Git/Workflow/Stage

From KitwarePublic
< Git‎ | Workflow
Jump to navigationJump to search

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.

$ Create a Topic
...o----o  master,
        ^ *topic-name
$ Commit Changes
...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 HEAD will automatically use the topic-name:

$ git fetch stage --prune
$ git push stage HEAD
To git@public.kitware.com:stage/repo.git
* [new branch]      HEAD -> topic-name
...o----o  master, stage/master
         \
          o----o *topic-name, stage/topic-name

Viewing all Topics

Actions Results Troubleshooting

Print the current stage topic table:

$ 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  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:

$ ssh git@public.kitware.com stage repo state
branch  9138476e64ec082d7d507c430c7d3fb0d6a6b586 next
branch  b78573d359b74e11f1233a55ee3a0a257973dfa1 master
topic   171b4573096612971f3b8d227a5b372be3281ca4 topic-name
topic   f68c277ddb11780c560d376a864cc5706eb7cc62 other-topic
merged  9138476e64ec082d7d507c430c7d3fb0d6a6b586 f68c277ddb11780c560d376a864cc5706eb7cc62
...

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.

$ 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

Print the new state of the stage:

$ 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  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:

$ edit files
$ git commit
...o----o  master
         \
          o----o----o *topic-name
               ^ stage/topic-name

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

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

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

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.

Actions Results Troubleshooting

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.

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.

Actions Results Troubleshooting

Add a commit to the topic that reverts all its changes, such as using git revert.

$ git revert -n origin/master..HEAD
(If the topic has merges this may not work. Ask on the project mailing list.)
$ git commit
...o----o  master
         \
          o----o----o----o *topic-name
                    ^ stage/topic-name

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

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

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

Finally, push an empty ref to the stage to delete the topic:

$ git push stage :topic-name

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