From: ALBERTIN TIMOTHEE 11514771 <timothee.albertin@xxxxxxxxxxxxxxxxx> --- Documentation/gitworkflows.txt | 215 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt index 02569d061..3f1ddba82 100644 --- a/Documentation/gitworkflows.txt +++ b/Documentation/gitworkflows.txt @@ -464,6 +464,221 @@ in patches to figure out the merge base. See linkgit:git-am[1] for other options. +TRIANGULAR WORKFLOW +------------------- + +Introduction +~~~~~~~~~~~~ + +In some projects, contributors cannot push directly to the project but +have to suggest their commits to the maintainer (e.g. pull requests). +For these projects, it's common to use what's called a *triangular +workflow*: + +- The project maintainer publishes a repository, called **UPSTREAM** in +this document, which is a read-only for contributors. They can clone and +fetch from this repository. +- Contributors publish their modifications by pushing to a repository, +called **PUBLISH** in this document, and request a merge. +- Opening a pull request +- If the maintainer accepts the changes, he merges them into the + **UPSTREAM** repository. + +This workflow is commonly used on different platforms like BitBucket, +GitHub or GitLab which provide a dedicated mechanism for requesting merges. + +........................................ +------------------ ----------------- +| UPSTREAM | maintainer | PUBLISH | +| git/git |- - - - - - - -| me/remote | +------------------ <- ----------------- + \ / + \ / + fetch | \ / ^ push + v \ / | + \ / + ------------- + | LOCAL | + ------------- +........................................ + +Motivations +~~~~~~~~~~~ + +* Allows contributors to work with Git even if they don't have +write access to **UPSTREAM**. + +Indeed, in a centralized workflow, a contributor without write access +could write some code but could not send it by itself. The contributor +was forced to create a mail which shows the difference between the +new and the old code, and then send it to a maintainer to commit +and push it. This isn't convenient at all, neither for the +contributor, neither for the maintainer. With the triangular +workflow, the contributors have the write access on **PUBLISH** +so they don't have to pass upon maintainer(s). And only the +maintainer(s) can push from **PUBLISH** to **UPSTREAM**. +This is called a distributed workflow (See "DISTRIBUTED WORKFLOWS" +above). + +* Code review is made before integration. + +The goal of the triangular workflow is also that the rest of the +community or the company can review the code before it's in production. +Everyone can read on **PUBLISH** so everyone can review code +before the maintainer(s) merge it to **UPSTREAM**. It also means +that, in a free software, anyone can propose code without danger +for the stability of the software. + +* Encourages clean history by using `rebase -i` and `push --force` to +the public fork before the code is merged. + +This is just a side-effect of the "review before merge" mentionned +above but this is still a good point. + + + +Here are the configuration variables you will need to arrange your +workflow. + +Preparation as a contributor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Cloning from **PUBLISH**, which is a fork of **UPSTREAM** or an empty +repository. + +====================== +`git clone <PUBLISH_url>` +====================== + +Setting the behavior of push for the triangular workflow: + +=========================== +`git config push.default current` +=========================== + +Adding **UPSTREAM** remote: + +=================================== +`git remote add upstream <UPSTREAM_url>` +=================================== + +With the `remote add` above, using `git pull upstream` pulls there, +instead of saying its URL. In addition, the `git pull` command +(without argument) can be used to pull from **UPSTREAM**. + +For each branch requiring a triangular workflow, set +`branch.<branch>.remote` and `branch.<branch>.pushRemote` to set up +the **UPSTREAM** and **PUBLISH** repositories. + +Example with master as <branch>: +=================================== +* `git config branch.master.remote upstream` +* `git config branch.master.pushRemote origin` +=================================== + +Staying up-to-date +~~~~~~~~~~~~~~~~~~ + +Retrieve updates from **UPSTREAM** with `git pull` and send them to +**PUBLISH** with `git push`. + +Making your work available +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `git push` command sends commits to the **PUBLISH** repository and not to +the **UPSTREAM** thanks to the configuration you did earlier with the +`git config remote.pushdefault origin` command. + +When a contributor pushes something, the `git config push.default +current` command can be used to specifies that the name of the +**PUBLISH** branch is the same as the name of the **LOCAL** one. + +.Display the push remote's name: +[caption="Recipe: "] + +================================= +`git rev-parse --abbrev-ref @{push}` +================================= + +The shorthand `<branch>@{push}` denotes the remote-tracking branch +where the <branch> would be pushed to. If no <branch> is specified +(`@{push}`), <branch> takes the value of the current branch. + + +.Display the fetch remote's name: +[caption="Recipe: "] + +=================================== +`git rev-parse --abbrev-ref @{upstream}` +=================================== + +The shorthand `<branch>@{upstream}` substitutes the upstream name of +the branch. If no <branch> is specified (`@{upstream}`), <branch> +takes the value of the current branch. + +.Display commits added to the current branch since last push: +[caption="Recipe: "] + +=============== +`git log @{push}..` +=============== + +.Display commits added to a specific branch since last push: +[caption="Recipe: "] + +============================ +`git log <branch_name>@{push}..` +============================ + +Alternatively +~~~~~~~~~~~~~ + +Cloning from **UPSTREAM** +[caption="Recipe: "] + +In the preparation above, a clone from **PUBLISH** was used. Starting +with a clone of **UPSTREAM** is possible too. + +Cloning from **UPSTREAM** + +====================== +`git clone <UPSTREAM_url>` +====================== + +Setting the behavior of push for the triangular workflow: + +=========================== +`git config push.default current` +=========================== + +Because modifications will be often pushed into the **PUBLISH** repository, +instead of having to type its URL every time, a short name can be used +to call it. + +Adding **PUBLISH** remote: + +=================================== +`git remote add publish <PUBLISH_url>` +=================================== + +With the `remote add` above, using `git push publish` pushes there, +instead of saying its URL. In addition, `git push` can push to +**PUBLISH** without argument. + +'Method 1: One option for all branches' + +=================================== +`git config remote.pushDefault publish` +=================================== + +'Method 2: Each branch its option' + +Example with master as <branch>: +=================================== +`git config branch.master.pushRemote publish` +=================================== + + SEE ALSO -------- linkgit:gittutorial[7], -- 2.11.0