Skip to main content

Workflow

You now have a remote Git repository that serves up code shared by all developers, a local workflow, and you're familiar with basic Git commands. You're now ready to learn how to take advantage of some of the distributed workflows that Git offers.

Distributed Workflowsโ€‹

In contrast to a traditional centralized version control system (CVCS), Git's distributed nature makes collaboration between developers much more flexible and diverse. In a centralized system, each developer is like a node connected to a hub and works in much the same way as each other. In Git, each developer acts as both a node and a hub - that is, each developer can contribute their code to other repositories while maintaining their own public repository that others can work on and contribute code to.

Centralised workflowsโ€‹

A centralised workflow, a single point of collaboration model, is commonly used in centralised systems. A central hub, or repository, accepts code and everyone synchronises their work with it. Several developers then synchronise with the central repository as nodes, i.e. consumers of the central repository.

Integrating Manager Workflowsโ€‹

Git allows multiple remote repositories to exist, making it possible to have a workflow where each developer has write access to their own repository and read access to everyone else's. In this case, there is usually an authoritative repository that represents the "official" project. To contribute to this project, you need to clone your own public repository from that project and push your changes to it. You can then ask the maintainer of the official repository to pull updates and merge them into the main project. The maintainer can add your repository as a remote repository, test your changes locally, merge them into their branch and push them back to the official repository. The way this process works is shown below.

  1. The project maintainer pushes to the main repository.
  2. the contributor clones this repository and makes the changes.
  3. The contributor pushes the data to their own public repository. 4.
  4. The contributor sends an email to the maintainer requesting to pull their own updates.
  5. The maintainer adds the contributor's repository as a remote repository in their own local repository and merges the changes.
  6. The maintainer pushes the merged changes to the main repository.

Supervisor and Deputy Supervisor workflowโ€‹

This is actually a variation of the multi-repository workflow. It is usually used for very large projects with hundreds of collaborative developers, such as the famous Linux kernel project. Individual integration managers, called lieutenants, are responsible for specific parts of the integration project. Above all these lieutenants there is a general integration manager called a dictator who is responsible for the overall coordination. The dictator maintains a repository that acts as a reference repository for all collaborators to pull code for their projects. The whole process looks like this.

  1. normal developers work on their own topic branch and make base changes based on the master branch. Here is the master branch of the reference repository pushed by the supervisor. 2.
  2. the deputy supervisor merges the topic branch of the normal developer into his master branch. 3. the supervisor merges all the deputy supervisor's topic branches into his master branch.
  3. The supervisor merges all the master branches of the deputy supervisors into his own master branch. 4.
  4. finally, the supervisor pushes the integrated master branch to the reference repository so that all other developers can use it as a base for their changes.

Contributing to a projectโ€‹

The main difficulty in describing how to contribute to a project is that there are many different ways to do it. Because Git is so flexible and people can work together in different ways, it's not very accurate to describe how contributions should be made - every project is a little different. Influencing factors include the number of active contributors, the workflow chosen, commit permissions, and the external contribution methods that may be included.

The first influencing factor is the number of active contributors - the number of users actively contributing code to the project and how often they contribute. In many cases you may have two or three developers submitting several times a day, and for inactive projects it may be even less. For larger companies or projects, the number of developers may be in the thousands, with hundreds or thousands of commits a day. This is important because as there are more developers, there will be more problems in making sure your code can be applied cleanly or merged easily. Committed changes can show up as out of date, or they can be severely corrupted by merged-in work while you are making changes or waiting for them to be approved for application. How do you ensure that the code is always up to date and that commits are always valid?

The next influencing factor is the workflow used for the project**. Is it centralised, i.e. does every developer have the same write limit for the mainline code? Does the project have a maintainer or integrator who checks all patches? Are all patches peer-reviewed and then approved? Were you involved in that process? Does a lieutenant system exist where you have to submit your work to it first?

The next influencing factor is submission permissions. Having or not having write access to a project can make a huge difference to the process required to contribute to the project. If there is no write permission, how will the project choose to accept the contributed work? Is there even a specification of how to contribute? How much work do you contribute at a time? How often do you contribute?

Submission guidelinesโ€‹

Abstract with initial capital letters (no more than 50 characters)

Include more detailed explanatory text if necessary. Line breaks at approximately 72 characters.
In some cases, the first line is used as the title of an email and the rest of the text as the body.
A blank line separating the summary from the body is essential (unless you omit the body altogether).
If you mix the two, then tools such as ChangeBase will not work properly.

Use a directive style for commit messages: use "Fix bug" rather than "Fixed bug" or "Fixes bug".
This convention is the same as the git merge and git revert commands for generating commit notes.

A blank line follows a further paragraph.

- Bullets are also allowed.

- The bulleted symbol can be a typical hyphen or asterisk followed by a space, with blank lines separating the lines.
However, this can vary according to different conventions.

- Using hanging indents

Small private teamsโ€‹

Small private teams usually consist of more than two developers and have a relatively simple workflow: 1.

  1. John, the developer, clones the repository, makes the changes, and commits locally.

  2. Jessica, the developer, does the same thing - clones the repository and commits a change: 3.

  3. Jessica pushes her work to the server and everything works fine. 4.

  4. John makes some changes later, commits them to the local repository and then tries to push them to the same server. 5.

  5. At this point John's push fails because Jessica has already pushed her changes before. 6.

  6. because John must first grab Jessica's upstream changes and merge them into his local repository before he can be allowed to push them.

  7. In the first step, John crawls Jessica's work. 8.

  8. In the second step, John merges the work.

............

Private management teamsโ€‹

Contributors on a private team collaborate on a feature basis, and contributions from these teams will be consolidated by others.

  1. John and Jessica work on a feature branch (featureA). 2.
  2. Jessica is also working with a third developer, Josie, on a second feature branch (featureB). 3.
  3. the company uses an integration-manager workflow where the work of independent teams can only be integrated by specific engineers, and the master branch of the master repository can only be updated by those engineers. 4.
  4. In this case, all work is done on a team-based branch and is later pulled together by the integrator.

............

Derived public projectsโ€‹

The first example describes using derivation to contribute on a Git hosting that supports simple derivation. Many hosting sites support this feature (including GitHub, BitBucket, repo.or.cz, etc.), and many project maintainers expect this style of contribution.

The second example will discuss projects that prefer to accept contributed patches via email.

Public projects via Forkโ€‹

First, you might want to clone the main repository, create a topic branch for the patch or sequence of patches you plan to contribute, and then do the work there.

// Clone the remote repository
git clone <url>

// Switch to the project directory
cd project

// Create and switch to the feature branch
git checkout -b featureA

// ... Work ...
git commit

// ... work ...
git commit

When you're done with your branch and ready to contribute it back to the maintainer, go to the original project and click the Fork button to create a writable copy of your own project-derived repository. Then you need to add that repository as a new remote repository in your local repository, in this case called myfork.

// Add the fork repository
git remote add myfork <url>

// Push the feature branch
git push -u myfork featureA

Once work has been pushed to your derived repository, you need to notify the maintainers of the original project that you have work that you want them to merge. This is often called a Pull Request, and you can usually generate it via the website. You can also run the git request-pull command and email the subsequent output to the project maintainer manually.

On a project where you are not the maintainer, it is often convenient to have a master branch that always keeps track of origin/master, working on topic branches because you can easily discard them if they are rejected. If the master repository moves at the same time and your commits no longer apply cleanly, then making the working topic independent of the topic branch will also make it easier to rebase your work.

For example, if you want to provide a second feature to work on a project, don't continue working on the topic branch you just pushed - restart from the master branch of the master repository at.

Public projects via emailโ€‹

First, you clone the master repository and do the work there.

// Clone the remote repository
git clone <url>

// Switch to the project directory
cd project

// Create and switch to the feature branch
git checkout -b topicA

// ... work ...
git commit

// ... work ...
git commit

Now you have two commits to send to the mailing list. Use git format-patch to generate an mbox-formatted file that can be mailed to the list - it converts each commit into an email, with the first line of the commit message as the subject and the rest of the message with the patch introduced by the commit as the body.

git format-patch -M origin/master

// Patch file
<file-name>.patch
<file-name>.patch

To mail it to a mailing list, you can either paste the file into an email client or send it via a command line program.

// Use this command provided the local mail server is set up correctly.
git send-email <file-name>.patch

Maintaining projectsโ€‹

As well as how to participate effectively in contributing to a project, you may also need to understand how to maintain it. This involves accepting and applying patches generated and emailed by others using format-patch, or integrating changes from remote repository branches added to a project. But whether it's managing the repository, or helping to validate and review incoming patches, there needs to be some kind of long-term sustainable way of working agreed with other contributors.

Working in topic branchesโ€‹

It's like creating a feature branch locally. After adding contributors whose commit branches pass local testing, it's time to consider whether to merge them into a long term branch.

Applying patches from mailโ€‹

Applying patches with the apply commandโ€‹

If you receive a patch created using git diff or a variant of the Unix diff command (this is not recommended, see the next section), you can apply it using the git apply command. Assuming you have saved the patch in /tmp/patch-ruby-client.patch, you can apply the patch like this.

git apply /tmp/patch-ruby-client.patch

Applying patches using the am commandโ€‹

If the contributor of the patch is also a Git user and is skilled at using the format-patch command to generate patches, your job will be easier because the patch will contain author information and commit information for your reference.

To apply a patch generated by the format-patch command, you should use the git am command.

git am <file-name>.patch

Checking out remote branchesโ€‹

If your contributor has created their own repository, pushed a number of changes into it, and then sent you the URL of the repository and the remote branch containing the changes, then you can add it as a remote branch and merge it locally.

Integrating contributed workโ€‹

Merging workflowsโ€‹

A basic workflow is to merge all work directly into the master branch. In this case, the code contained in the master branch is largely stable. When you finish work on a topic branch, or review the work contributed by others, you merge it into the master branch, then delete the topic branch, and so on.

Large Project Merge Workflowโ€‹

Git projects have four long-running branches: master, next, pu (proposed updates) for new work, and maint, which is for maintenance backports. New work from contributors is included in topic branches in a similar fashion to the one described earlier (see Managing a complex series of parallel topic branches that receive contributions.) The topic branches are then tested and evaluated. The topic branches are then tested and evaluated to see if they are ready to be merged or if they still need more work. A safe topic branch is merged into the next branch, which is then pushed to make it possible for everyone to try to integrate the features together.

Variable base and picking workflowsโ€‹

To maintain a linear commit history, some maintainers prefer to base and pick work contributed on the master branch rather than merging it directly. When you have completed work in a topic branch and decide to merge it, you can run the rebase command in that branch to reconstruct the changes from the current master branch (or a branch such as develop).

Tagging a releaseโ€‹

When you decide to make a release, you may want to tag it so that you can recreate it at any subsequent commit point.

Generating a Build Numberโ€‹

Git doesn't have a sequence of numbers like v123 that increments with each commit, so if you want to attach a readable name to a commit, you can run the git describe command on it. In response, Git will generate a string consisting of the name of the most recent tag, the number of commits since that tag, and the partial SHA-1 value of the commit you're describing (the g prefix indicates Git).

git describe master
v1.6.2-rc1-20-g8c5b85c

Preparing a Releaseโ€‹

Now you're ready to release a build. One of the things you can do is create an up-to-date snapshot archive for those poor packages that don't use Git. Use the git archive command to do this.

git archive master > archive.zip

Creating a commit briefingโ€‹

Now it's time to notify those on your mailing list who are curious about what's happening with your project. Use the git shortlog command to quickly generate a changelog-type document containing what has been added to the project since the last release.

// including all commits since v1.0.1
git shortlog --no-merges master --not v1.0.1