Manage and share files with Git
Many Branches
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
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.
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 [...]
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
New Slimbook EVO with Raw AMD Ryzen Power
If you're looking for serious power in a 14" ultrabook that is powered by Linux, Slimbook has just the thing for you.
-
The Gnome Foundation Struggling to Stay Afloat
The foundation behind the Gnome desktop environment is having to go through some serious belt-tightening due to continued financial problems.
-
Thousands of Linux Servers Infected with Stealth Malware Since 2021
Perfctl is capable of remaining undetected, which makes it dangerous and hard to mitigate.
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.