10 useful Git commands for collaborative development

The more people working on a given project, the more work organization it requires. Thus, Git is commonly used to coordinate work among programmers. However, without enough knowledge, using git can become a nightmare. Instead of helping, it only hinders. Instead of keeping control of the repository, you end up with tons of conflicts in your code.

In this article, I will show you super useful git commands to avoid a mess and make working in a team much easier.

Disclaimer: This article uses the official Git naming convention, so the default branch is named master. However, more and more providers, including Github no longer use master name. They have switched their default branch name to main.

Golden Rule: keep your code independent

Before we start, one golden rule needs to be highlighted.

Do not work directly on the master branch.

Anything in the master branch is always deployable. Create your own branch or checkout to existing one. In the perfect scenario, a single branch corresponds to developing a single software feature. Once you’re done with a feature branch, create a pull request to merge changes with master. Moreover, adding a reviewer is a really good practice.

Protect master branch 

In repository settings on Github/Bitbucket you can define protection rules for master branch (or any other important one). You can protect it from deleting or forcing push changes. 

10 useful Git commands

1. Move uncommitted changes to another branch 

It may happen that you start modifying the master branch (or any other one) by mistake. In such case move your uncommitted changes to another branch.

git switch -c [new-branch-name]    # run this command on the old branch
# or
git stash                          # run this command on the old branch 
git stash pop                      # run this command on a new branch

If you commit your changes, you can undo this commit. Take a look at the next command.

2. Undo your n last commits

  • commits that have not been pushed
git reset --soft HEAD~[n]     # wse --soft to keep your changes
git reset --hard HEAD~[n]     # use --hard to discard the changes
  • pushed commits
git revert [commit-hash]                                # for a single commit
git revert [oldest-commit-hash]..[latest-commit-hash]   # for mulitple commits

As a result, you’ll undo commit push. Commit is no longer in the remote repository, but it still exists in your local version. It’s up to you what you’ll do next — you can undo the local commit using git reset for instance. 

Extra: To check which commits are on your local [branch-name] but not yet on origin/[branch-name] use:

git log origin/[branch-name]..[branch-name]

3. Integrate master updates with your branch

You’re working on your branch, but master has changed over time? Pull changes from master and apply them to your branch.

git checkout master
git pull                        # pull changes from master
git checkout [branch-name]
git rebase master

4. Squash commits 

If your repository has a series of related commits that can be combined into one, consider squashing them before submitting a pull request. Related commits usually mean that they address a single issue or feature.
Commit squashing can be done by using Git’s Interactive Rebase feature.

Note: Show commit history by using: git log --oneline

Suppose that we have 5 commits. 

d86c31d (HEAD -> branch) Commit 5
5c6a393 Commit 4
6586d82 Commit 3
20602ed Commit 2
7191fa7 Commit 1

We’d like to squash Commit 3 and Commit 4. Let’s run an interactive rebasing session for 4 last commits (flag -i/ — interactive).

git rebase -i HEAD~4

The output is as follows:

pick 20602ed Commit 2
pick 6586d82 Commit 3
pick 5c6a393 Commit 4
pick d86c31d Commit 5

Change mode pick to squash for Commit 4 since we’d like to squash it with the previous commit (you can use s as a shortcut).

pick 20602ed Commit 2
pick 6586d82 Commit 3
squash 5c6a393 Commit 4
pick d86c31d Commit 5

Now, you’ll need to edit the commit message for squashed commits.
Lines starting with # will be ignored, so if you don’t want to save some commit message, just comment it out. 

Old commit messages: 

# This is a combination of 2 commits.
# This is the 1st commit message:

Commit 3

# This is the commit message #2:

Commit 4

Message for a combination of Commit 3 and Commit 4:

# This is a combination of 2 commits.
# This is the 1st commit message:

Commit 3 and 4

# This is the commit message #2:

# Commit 4

Now, the commit history looks like this:

5e3dda8 (HEAD -> master) Commit 5
b338128 Commit 3 and 4
20602ed Commit 2
7191fa7 Commit 1

Make a forced push to push changes to the remote repository. 

git push -f origin [branch-name]

Extra: Modifying commit message 

Renaming commits can be done in the same manner as squashing commits. The main difference is to change pick commit mode to reword / r in front of any commits, you want to fix.

5. Undo git rebase

Did you mess up your git history and you want to undo the finished rebase?
No worries. 

Find the head commit of the branch committed before starting the rebase.  
Use the following command:

git reflog

Example of the output:

...
0db408b HEAD@{20}: rebase (finish): returning to refs/heads/master
0db408b HEAD@{21}: rebase (pick): Commit 5
cdcbfb1 HEAD@{22}: rebase (squash): Commit 2
d5cf7f2 HEAD@{23}: rebase (squash): # This is a combination of 2 commits.
...

Let’s say that I’d like to restore the state from Commit 5. This commit is HEAD@{21} in the ref log. Reset the git history using this reference. 

git reset --hard HEAD@{21}

6. Add changes to the latest commit. 

It’s a super useful command, especially when you made a typo or forgot to add some changes to recently committed code.

git add [filename]
git commit --amend --no-edit
git push -f origin [branch-name]

The -f / —force option must be used to push an amended commit.

7. Get the remote branch that doesn’t exist locally 

A new branch was added to remote repository but it’s not visible in your local version? Fetch it or switch to it.

git fetch origin [remote-branch-name]:[local-branch-name]
# or
git switch [remote-branch-name]

8. Clone specific branch from the remote repository.

git clone -b [branch-name] [remote-repository]

9. Compare file content between different branches.

git diff [branch-1]:[filename] [branch-2]:[filename]

10. Rename the branch you working on 

Rename the branch locally and remotely. 

git checkout [old-name-branch]
git branch -m [new-name-branch]
git push origin -u [new-name-branch]
git push origin -d [old-name-branch]

Note: origin is a shorthand name for the remote repository that a project was originally cloned. It’s used instead of that original repository URL. Name origin is only a convention.


Summary

The commands presented above are not the commands you learn when you use git for the first time. However, they can significantly improve your work with colleagues on the project. If you are afraid of messing up everything in the big project git history, start low. Create your private project, multiple branches, and … experiment. Pay additional attention to commands that change git history, e.g. git rebase / git reset . Use them carefully and with solid understanding. 

Leave a Reply