Manage and share files with Git

Many Branches

© Lead Image © germina, 123RF.com

© Lead Image © germina, 123RF.com

Article from Issue 217/2018
Author(s):

Software projects often comprise several code branches, some of which exist in parallel. Git supports community code development through remote repositories and code branching.

Special Thanks: This article was made possible by support from Linux Professional Institute

Real projects usually are not linear: When many developers work on code, parallel branches are the rule. Git allows you to store your code branches in a repository (repo), and even changing the directory structure does not cause any problems.

The example from the first part of this series [1] comprises three text files located in a local repository, which is usually sufficient just to manage files. However, if you work in a team, being able to link your project to a remote repository has advantages.

The corresponding git commands you will use are clone (create and check out a project), push (transfer data to the remote repository), fetch (get data from a remote repository), and pull (get and merge data). In this context, the term "data" represents the linked or specified references and objects in the Git index.

Into the Past

Figure 1 shows the status of the project at the end of the first part of the workshop with the command

git log --oneline --decorate --graph
Figure 1: Determining the status of a project. The current branch is illustrated at the bottom.

The project contains four commits arranged on a timeline. With the exception of the first commit, each is based on its predecessor. This line is known as a branch.

The HEAD is a pointer to the version on which the current working directory is based (i.e., the end of the checked out branch). The entries named origin refer to the remote repository from which you cloned the project – in this case, the origin remote repository. The information reflects the status of the last synchronization. The names master (for branches) and origin (for the repository that is the source for the local repository) are defaults that Git assigns if you do not make any explicit specifications.

Branches

Branches allow concurrent development. Typically, the main branch contains the completed or already delivered versions; further development takes place in other branches. Ideally, each task has its own branch with a meaningful name. Once you have completed the changes in each branch, you transfer them to the main branch and test them, and the new version is ready.

Git acts as a decentralized version control system. You can create branches without a connection to the remote repository and transfer them back later if necessary. Furthermore, Git treats all branches equally. The known commands work as usual and as speedily.

The following two commands create a new branch, whose starting point is the currently checked out state, and then switch to the respective branch:

git branch mybranch
git checkout mybranch

The working directory contains the status of the last commit in the specified branch. If the branch does not yet exist, the command

git checkout -b mybranch

combines both actions.

Figure 2 shows a project with the master and mybranch branches. The master branch contains the finished versions MA and MB; development takes place in mybranch, which already has the intermediate versions ZA, ZB, and ZC.

Figure 2: Branches divide a project into units, which you can complete and then add back to the main branch.

You can switch between branches with the commands:

git checkout master
git checkout mybranch

However, it only works if there are no changes in the working directory. A working directory in this state is referred to as "clean." To add changes, use

git add -u
git commit -m ...

or reset the changes with:

git reset --hard

You should regularly check whether all files are in the Git index by running git status or cloning to a test directory.

Git offers another approach of saving the changed data with the git stash command, which occurs in a special area of the local repository. You can import the changes into the working directory at any time, regardless of the version checked out. For more details, see the corresponding man page (i.e., git stash --help) and the online book Pro Git [2].

Git creates the branches in the local repository. To include them in the remote repository, you need to create an appropriate link. The push command from the first line of Listing 1 creates the link and starts the data transfer. This is followed by both branches, master and mybranch, in hot pursuit. If several people are working on a branch or you want to make a backup copy of the branch, transfer the branch to the remote repository.

Listing 1

Push to Remote Repo

$ git push --set-upstream origin mybranch
[...]
$ git remote show origin
  HEAD branch: master
  Remote branches:
    master     tracked
    mybranch   tracked
  Local branches configured for 'git pull':
    master     merges with remote master
    mybranch   merges with remote master
  Local refs configured for 'git push':
    master     pushes master      (up to date)
    mybranch   pushes to mybranch (up to date)

The git branch -a command displays the local and remote branches. Anyone who has the appropriate access rights can check out these branches. Cloning puts all branches contained in the remote repository on your disk. If you do not specify a branch, the working directory contains the latest status of master. Branches checked out of the remote repo always have the status tracked.

Make your changes on the branch as often as you like. If you reach a good version, merge this branch with the master.

Merge

Merging merges the changes from branches. In Figure 2, mybranch is derived from the last commit of the master branch. Because no changes to master have taken place, the blue path describes the merge process performed with the commands in Listing 2.

Listing 2

Merge Example

$ git checkout master
Switched to branch 'master'
$ git merge mybranch
Updating 6466a1f..eff29ab
Fast-forward
[...]
$ git log --oneline --decorate --graph --all
* 9dd9027 (HEAD -> mybranch, origin/mybranch, origin/master, origin/HEAD) project file processed
[...]

In this case, Git shifts the HEAD pointer to the last commit in mybranch. This process is known as a fast-forward. After merging, both branches have the same status. If master changed in the meantime, Git searches for the changes (a three-way comparison) from the common starting point of both branches (in this case, MB) and tries to synchronize them.

If the changes are in different places or affect different files, everything works as described. The software checks in the new version resulting from the merge as part of the process. Unless otherwise specified, Git starts the editor, so you can enter a corresponding message.

A change in the same place is a conflict (Listing 3). Git prints the names of the corresponding files and identifies the conflicts within the files (Figure 3). Once you have resolved the problems, the commands

git add -u
git commit -m ...

move the resulting state into the Git database.

Listing 3

Merge Conflict

$ git checkout master
Switched to branch 'master'
$ git merge mybranch
Auto-merging init.c
CONFLICT (content): Merge conflict in init.c
Automatic merge failed; fix conflicts and then commit the result.
$ git status
[...]
#     both modified:   init.c
[...]
Figure 3: Merge problems: The software does not have a solution, so the only option is to examine the differences manually and then adopt the desired version.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Tree View

    Complex Git projects sometimes require a better view of the dependencies and branches. Several tools offer GUI options for Git. We take a look at gitk, gitg, git-gui, and GitAhead.

  • Git 101

    When several people collaborate on source code or documents, things can get messy fast. Git provides a quick cure: The distributed versioning system reliably ensures the integrity and consistency of data with minimal effort.

  • Perl: Collaborate with GitHub

    GitHub makes it easier for programmers to contribute to open source projects by simplifying and accelerating communications between project maintainers and people willing to contribute.

  • Version Control with Git

    The Git version control system is a powerful tool for managing large and small software development projects. We'll show you how to get started.

  • GitX Clone Gitg Moves to 0.0.4

    The young Gitg project, which visualizes a graphical representation of git data for Mac OS X under Gtk+/GNOME, allows check-ins and merges in its newest release 0.0.4, among other things.

comments powered by Disqus

Direct Download

Read full article as PDF:

Price $2.95

News