Published by Marco on 24. Jul 2015 10:29:39
------------------------------------------------------------------------

Encodo first published a Git Handbook for employees in September 2011 and last
updated it in July of 2012. Since then, we've continued to use Git, refining our
practices and tools. Although a lot of the content is still relevant, some parts
are quite outdated and the overall organization suffered through several
subsequent, unpublished updates.

What did we change from the version 2.0?

  * We removed all references to the Encodo Git Shell. This shell was a custom
    environment based on Cygwin. It configured the SSH agent, set up environment
    variables and so on. Since tools for Windows have improved considerably, we
    no longer need this custom tool. Instead, we've moved to PowerShell and
    PoshGit to handle all of our Git command-line needs.
  * We removed all references to Enigma. This was a Windows desktop application
    developed by Encodo to provide an overview, eager-fetching and batch tasks
    for multiple Git repositories. We stopped development on this when SmartGit
    included all of the same functionality in versions 5 and 6.
  * We removed all detailed documentation for Git submodules. Encodo stopped
    using submodules (except for one legacy project) several years ago. We used
    to use submodules to manage external binary dependencies but have long since
    moved to NuGet instead.
  * We reorganized the chapters to lead off with a quick overview of Basic
    Concepts followed by a focus on Best Practices and our recommended
    Development Process. We also reorganized the Git-command documentation to
    use a more logical order.

You can download "version 3 of the Git Handbook"
 or
"get the latest copy from here"
. 

Chapter 3, Basic Concepts and chapter 4, Best Practices have been included in
their entirety below.

[3 Best Practices]

[3.1 Focused Commits]

Focused commits are required; small commits are highly recommended. Keeping the
number of changes per commit tightly focused on a single task helps in many
cases.

  * They are easier to resolve when merge conflicts occur
  * They can be more easily merged/rebased by Git
  * If a commit addresses only one issue, it is easier for a reviewer or reader
    to decide whether it should be examined.

For example, if you are working on a bug fix and discover that you need to
refactor a file as well, or clean up the documentation or formatting, you should
finish the bug fix first, commit it and then reformat, document or refactor in a
separate commit.

Even if you have made a lot of changes all at once, you can still separate
changes into multiple commits to keep those commits focused. Git even allows you
to split changes from a single file over multiple commits (the Git Gui provides
this functionality as does the index editor in SmartGit).

[3.2 Snapshots]

Use the staging area to make quick snapshots without committing changes but
still being able to compare them against more recent changes.

For example, suppose you want to refactor the implementation of a class. 

  * Make some changes and run the tests; if everything’s ok, stage those changes
  * Make more changes; now you can diff these new changes not only against the
    version in the repository but also against the version in the index (that
    you staged).
  * If the new version is broken, you can revert to the staged version or at
    least more easily figure out where you went wrong (because there are fewer
    changes to examine than if you had to diff against the original)
  * If the new version is ok, you can stage it and continue working

[3.3 Developing New Code]

Where you develop new code depends entirely on the project release plan.

  * Code for releases should be committed to the release branch (if there is
    one) or to the develop branch if there is no release branch for that release
  * If the new code is a larger feature, then use a feature branch. If you are
    developing a feature in a hotfix or release branch, you can use the optional
    base parameter to base the feature on that branch instead of the develop
    branch, which is the default.

[3.4 Merging vs. Rebasing]

Follow these rules for which command to use to combine two branches:

  * If both branches have already been pushed, then merge. There is no way
    around this, as you won’t be able to push a non-merged result back to the
    origin.
  * If you work with branches that are part of the standard branching model
    (e.g. release, feature, etc.), then merge.
  * If both you and someone else made changes to the same branch (e.g. develop),
    then rebase. This will be the default behavior during development

[4 Development Process]

A branching model is required in order to successfully manage a non-trivial
project.

Whereas a trivial project generally has a single branch and few or no tags, a
non-trivial project has a stable release—with tags and possible hotfix
branches—as well as a development branch—with possible feature branches.

A common branching model in the Git world is called Git Flow. Previous versions
of this manual included more specific instructions for using the Git Flow-plugin
for Git but experience has shown that a less complex branching model is
sufficient and that using standard Git commands is more transparent.

However, since Git Flow is a very widely used branching model, retaining the
naming conventions helps new developers more easily understand how a repository
is organized.

[4.1 Branch Types]

The following list shows the branch types as well as the naming convention for
each type:

  * master is the main development branch. All other branches should be merged
    back to this branch (unless the work is to be discarded). Developers may
    apply commits and create tags directly on this branch.
  * feature/name is a feature branch. Feature branches are for changes that
    require multiple commits or coordination between multiple developers. When
    the feature is completed and stable, it is merged to the master branch after
    which it should be removed. Multiple simultaneous feature branches are
    allowed.
  * release/vX.X.X is a release branch. Although a project can be released (and
    tagged) directly from the master branch, some projects require a longer
    stabilization and testing phase before a release is ready. Using a release
    branch allows development on the develop branch to continue normally without
    affecting the release candidate. Multiple simultaneous release branches are
    strongly discouraged.
  * hotfix/vX.X.X is a hotfix branch. Hotfix branches are always created from
    the release tag for the version in which the hotfix is required. These
    branches are generally very short-lived. If a hotfix is needed in a feature
    or release branch, it can be merged there as well (see the optional arrow in
    the following diagram).

The main difference from the Git Flow branching model is that there is no
explicit stable branch. Instead, the last version tag serves the purpose just as
well and is less work to maintain. For more information on where to develop
code, see “3.3 – Developing New Code”.

[4.2 Example]

To get a better picture of how these branches are created and merged, the
following diagram depicts many of the situations outlined above.

The diagram tells the following story:

  * Development began on the master branch
  * v1.0 was released directly from the master branch
  * Development on feature “B” began
  * A bug was discovered in v1.0 and the v1.0.1 hotfix branch was created to
    address it
  * Development on feature “A” began
  * The bug was fixed, v1.0.1 was released and the fix was merged back to the
    master branch
  * Development continued on master as well as features “A” and “B”
  * Changes from master were merged to feature “A” (optional merge)
  * Release branch v1.1 was created
  * Development on feature “A” completed and was merged to the master branch
  * v1.1 was released (without feature “A”), tagged and merged back to the
    master branch
  * Changes from master were merged to feature “B” (optional merge)
  * Development continued on both the master branch and feature “B”
  * v1.2 was released (with feature “A”) directly from the master branch

[image]
Legend:

  * Circles depict commits
  * Blue balloons are the first commit in a branch
  * Grey balloons are a tag
  * Solid arrows are a required merge
  * Dashed arrows are an optional merge