Language
Category
Search

Learning the basics of Git and the use of branches

An introduction to git: how to set up in a project, define basic configurations, manage branches, view histories and deal with conflicts

At Terminal By Rudi Drusian Lange
Published on
Last updated

About

From the manual: Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.

Help

To consult the Git manual, use man git. There are two ways to find out more about a specific git command such as git log: man git-log or git help log.

Starting a project 

First of all, it's good practice to set up the name and email address that will be used in the projects:

Shell

git config --global user.name "Your Name Here"
git config --global user.email your@email.com

Assuming that the project to be managed is in the my-project folder, initialize Git:

cd my-project
git init

Initialized empty Git repository in .git/

A new .git/ directory has been created inside the my-project folder. Next, to take a snapshot of the contents of all files under the current directory, use:

# The dot '.' represents the current directory
git add .

Using git add the snapshot is temporarily saved in the index, to store the contents of the index permanently use:

git commit

Initial commit
# Please enter the commit message for your changes. Lines starting  # with '#' will be ignored, and an empty message aborts the commit. ...

You will be asked to enter a message to define this commit - in this example, Initial commit was used. Not typing a message cancels the process. The vi editor was used, Esc + i enables text editing mode, after typing the message, save and exit by pressing Esc and then typing :wq (write and quit).

You can also set the message on the command line using -m:

git commit -m "Initial commit"

Modify some files, add the updated content to the index and commit. Below are some useful commands to help with the process.

# add multiple files to the index
git add file1 file2 file3

# shows changes that have not been added to the index
git diff

# shows changes already in the index but not yet committed
git diff --cached # returns a summary of the situation git status # remove a file from the index git restore --staged file-name

Remember to type the commit message, then save and exit.

git commit -a

The above command will identify any changes to pre-existing files, add them to the index and commit, all at the same time. New files will be ignored.

It's good practice to use the first line of the commit message as a title, something that summarizes the change being made in less than 50 characters. Leave a blank line after the title and write a more detailed message. The text up to the first blank line is treated as the commit title and will be used in various situations in the git command.

For example, git format-patch turns commit into an email, uses the title as the subject and the rest of the commit text in the body.

Project history

The history can be consulted at any time using the git log command.

# commit history
git log

# complete diffs at each step
git log -p

# overview of changes
git log --stat --summary

Managing Branches

Branches are used to manage a new project based on the original. A single Git repository can maintain multiple branches of development.

# Creating a new branch called experimental
git branch experimental

List of all existing branches, asterisk marks the current branch.

git branch

  experimental 
* master

Switching to the experimental branch:

git switch experimental

Switch to the experimental branch using the command above, edit any file and then execute the following commands to commit and switch back to master branch.

git commit -a
git switch master

Check that the change made to the file while in the experimental branch is not present in the master. To merge the experimental branch with the master branch use the command:

git merge experimental

When merging the experimental branch into master, all edits to the experimental branch file will be added to master. In the example above, only the experimental branch file was edited.

If the edits were made to the same file in both branches, but on different lines, when merging the branches the two changes would be kept.

Practical example

Let's create the project.txt file with the following content and add it to both branches:

# switch to the master branch
git switch master

# create the project.txt file
vi project.txt

project.txt

1
2
3
# add project.txt to the index
git add project.txt

# commit
git commit -a   

# switch to the experimental branch
git switch experimental

# merge all changes made to master including a copy
# of the project.txt file to the experimental branch
git merge master

When committing, remember to add a description, write and quit.

Add the number 0 to the first line of the project.txt file from the experimental branch and add the number 4 to the end of the same file from the master branch.

vi project.txt

project.txt | experimental branch

0
1
2
3
git commit -a 
git switch master  
vi project.txt

project.txt | master branch

1
2
3
4
git commit -a
git merge experimental

When merging the experimental branch with master, the above command will produce the following result:

project.txt | master branch

0
1
2
3
4

It is worth remembering that in the experimental branch the file remains the same, with 0,1,2,3. 

Conflicts

If changes were made on the same line in both the master and experimental branches, when using the merge command a conflict error would be displayed and the process interrupted asking for resolution. In this case, Git doesn't know which of the changes to keep and therefore needs human intervention to resolve the conflict.

Continuing the previous example, now switch to the experimental branch, add -1 to the first line, commit, return to the master branch, add +1 to the first line and commit.

Before merging the branches, let's see how each file looks now:

project.txt

# master branch     # experimental branch
+1                  -1
0                    0
1                    1
2                    2
3                    3
4

Merging:

git merge experimental
                                                                   
Auto-merging project.txt CONFLICT (content): Merge conflict in project.txt Automatic merge failed; fix conflicts and then commit the result.

Git diff will display this and other existing conflicts and is used precisely for this purpose.

git diff

To resolve the conflict we will use the command:

git mergetool

This command will not necessarily open an editor to resolve the conflict unless you have one of the supported options installed. In this example we'll use vimdiff, but if you have access to the graphical interface it may be an advantage to use gvimdiff. Run the following configurations in Git:

# Set vimdiff as default
git config merge.tool vimdiff
#  Sets the diff3 style for displaying conflicts git config merge.conflictstyle diff3
# Doesn't prompt the editor message git config mergetool.prompt false

Help on the above commands can be found using:

git help config mergetool

# List of supported editors
git mergetool --tool-help

Resolving the conflict:

git mergetool

vimdiff

╔═══════╦══════╦════════╗
║       ║      ║        ║
║ LOCAL ║ BASE ║ REMOTE ║
║       ║      ║        ║
╠═══════╩══════╩════════╣
║                       ║
║        MERGED         ║
║                       ║
╚═══════════════════════╝

These 4 views are:

  • LOCAL: file from the current branch (master in our example)
  • BASE:  version before the changes, the common ancestor
  • REMOTE: file from the branch we are merging with (experimental in our example)
  • MERGED: this is the merge result, which will be used in the future

In vimdiff the shortcut Ctrl + W 2x is used to navigate between windows. Use the :help window-moving command within the editor for more information about navigating between windows.

To choose which version to use, press Esc and then type:

vimdiff

# To use the base file
:diffg BA
# To use the local file :diffg LO   # To use the remote file :diffg RE

Now save, close, commit and clean:

# Save and close vimdiff
Esc :wqa

# Commit
git commit -m "message"

# Removes additional files (e.g. *.orig)
# Beware! untracked files will be removed
git clean -f

You can also edit the merged file by typing new code and saving it instead of using one of the available versions.

History

The following command shows a nice graphical representation of the change history. Here the messages used for each commit will make better sense.

gitk

Delete

At this point the experimental branch has served its purpose of changing the project without compromising the original version and can be exclude, run the command:

git branch -d experimental

This command checks whether the changes to the experimental branch have already been applied before deletion. If you've developed a bad idea and want to discard the changes from this branch, use:

git branch -D bad-idea

Conclusion

Use and abuse branches, they're easy and cheap :-), it's a great way to try something different.

This article has been divided into parts so that it is not too long and discourages reading, you can continue learning about Git by reading on: Using Git to share and collaborate on a project, which is the continuation of this article.

Sources

This is not my original language and I don't speak it very well. I used my little knowledge and translators tools to compose the text of this article. Sorry for possible spelling or grammatical errors, suggestions for corrections are appreciated and can be sent to the contact email in the footer of the site. My intention is to share some knowledge and I hope this translation is good enough.