- Getting started with git
- Basic git workflow
- Create your own repository
- Remote Repositories
- Working with branches
- Pull or Merge Requests
- CI/CD Pipelines
Getting started with git
This is just a list of useful commands and practices I learned over time while using git.
Basic git workflow
The following chapters are the simple commands to get you started.
Clone a repository
Create a local clone:
git clone URI
Git supports different protocols, typically you use one of the below:
# clone for GitLab, GitHub etc. via HTTPS git clone https://github.com/ansible/ansible.git # if you want to commit to a repo, it is often more efficient to use SSH git clone firstname.lastname@example.org:ansible/ansible.git
When you work in your local repository:
# review current status git status # after editing a file, save and commit git add path/to/file git commit -m "useful commit message" # you can combine the two previous commands git commit -m "commit and add files" -a # delete a file from the repository git rm path/to/file # and commit the change git commit -m "delete path/to/file since it's obsolete"
This was only saving your change locally and did not (yet) push it to your remote! You can do many changes without pushing to your remote, depending on your work style and collaboration mode.
Pull updates and push changes
# only fetch latest changes, but do not merge them! git fetch # get all changes in all remote branches - particularly helpful if you want to see what others changed in their branches - but does not merge them! git fetch --all # get latest changes from remote and merge them locally git pull # push changes to remote git push
NOTE: If the remote has a newer version of the branch than your local repository, a
git push will give you an error message. In this case run
git pull again to fetch and merge the latest changes from the remote repository.
Git keeps all commits and you can review them with
git log. You can also see more details:
# history of all changes git log # git more details about a specific commit git show <commit> # show differences git diff <commit> # roll back previous change git checkout <commit> # switch back to last commit git checkout HEAD
Create your own repository
I recommend to always use git - even if you’re not sure yet you want to keep your work. Creating a git repository is just one simple command and therefore comes with very little cost:
# create a work directory mkdir my_new_project && cd my_new_project # initialize repository git init
Now you can do local edits, revert changes, do diffs and when you’re done, add a remote repository later. If you realize it was all in vain, you can just delete the entire directory.
Since git is a decentralized software management tool yo can add and remove remote repositories at any point in time and you can use multiple remotes as well.
# add a new repository git remote add <name> <URI> # get a list of all remotes currently configured git remote -v # remove a remote repository git remote remove <name>
All git commands like pull, push, diff etc. support different remotes, so you can easily compare their different states and decide where to pull or push changes to/from. I find it difficult at times to work with too many remotes, and seem to get lost in what’s where, so I would personally suggest not to stress this concept too much…
Cleaning your local directory
When working with Pull or Merge requests you often have local branches which have been deleted on the remote repository. You can clean them up easily:
# delete remote branches from local working directory git remote prune <name> # identify local branches which no longer exist on the remote git branch -v # delete local abandoned branches git branch -d <branch name> # if you have uncommitted changes git branch -D <branch name> # do everything in one command, but only for branches which have been merged LANG=C git branch -d `git branch -vv | grep deleted | cut -f3 -d' '`
Working with branches
Git loves branches. It’s always a good idea to create a new branch before you implement a new feature (remember the old days when you created script-v1.sh, script-v2.sh, script-20200802.sh and lost track which script has which change?).
# create a new branch from the current one git checkout -b <new branch> # switch between branches git checkout <old branch>
Sometimes you have a local change which you want to keep but not yet commit. Or you accidentally started to work in the wrong branch. Instead of copying your local changes to /tmp or similar hacks, you can use
# stash local changes without committing them git stash # apply the stashed changes again git stash apply
You can also work with different stashes by assigning names, check
git stash -h for more details.
Sometimes there are many changes you need to identify them. I find it useful to do the following list of commands:
# differences between branches git diff <branch> # sometimes the reversed output is more useful git diff -R >branch> # just find hte list of modified files git diff -R <branch> --name-only
After you finished your work in the new branch, you want to merge it back to master (or any other branch).
# switch to the target branch, e.g. master git checkout master # merge changes from the other branch git merge <branch> # sometimes you want to review changes and apply them individually, this will use the editor specified in the EDITOR environment variable if you want to edit the changes git checkout -p <branch> # merge a specific file from the other branch git checkout <branch> -- path/to/file
When merging branches conflicts often occur. While git is quite clever in solving many of them automatically, you will still have some which will require manual fixes.
# merge with master or other branch git merge <branch> # assume a conflict happens, solve it with your favorite editor vi file/with/conflict # add the files to your next commit git add files/with/conflict git commit -m "solving conflict" # or other meaningful commit message
Delete and cleanup
After your work is complete and has been merged, you can delete the local branch.
git branch -d <branch> # or, if there are uncommitted changes you don't want to keep git branch -D <branch>
Use check the chapter Cleaning your local directory.
Pull or Merge Requests
Git makes it easy to work with branches to keep track of new features, bug fixes, releases etc. To simplify collaboration in projects Merge Requests (GitLab) and Pull Requests (GitHub) can be used. These are not features of git, but capabilities provided by the respective platform. Specially when you’re new to git it can be difficult to differentiate between pure git functionality and these additional features.
Merge or Pull Requests are a good way to collaborate on new features or code changes. My typical workflow looks like this:
make sure your local repository is up to date by running
create a local branch to start development (
git checkout -b <new branch>)
make your changes, commit them and continue the typical workflow as described in basic git workflow
push the local branch to the remote (
git push, doing this the first time, you will probably see a message the remote branch does not yet exist and how you fix that, e.g.
git push -u origin local-branch)
you will see a link which will create the Merge or Pull Request - you can also navigate to the Web UI and create it from there
fill out the details, mark it as a draft or WIP (Work in Progress) - this will make sure nobody “accidentally” merges the branch until it’s ready
continue working on your branch (you can still push new changes to the same PR/MR, no need to delete it and create a new one!)
when you feel it’s ready, remove the draft or WIP flag
collaborate and discuss the proposed changes with your peers, push additional changes when needed
merge the changes
delete the branch created for this MR/PR
Merge from master
When working with MR/PR your branch might fall behind and new changes from master need to be merged into your branch:
# make sure master is up to date and optionally review changes git checkout master git pull # switch back to your branch git checkout <branch> # and merge all changes from master git merge <master> # or, review them while merging git checkout -p master # pull and merge in one command git pull <remote> <branch> # push your merged branch git push
Clean up merged branches
If you create a lot of branches to work on changes, you probably want to clean them up, after they got merged.
# clean orphaned remote branches git remote prune <remote> # find local branches which no longer exist on the remote git branch -v # delete those local branches which no longer exist on the remote git branch -d <branch> # if the branch was not fully merged and you know what you're doing git branch -D <branch> # you can do this in one command git branch -d `git branch -vv | grep gone | cut -f3 -d' '`
A very powerful feature which builds on top of SCM are pipelines. In GitLab CI/CD has been integrated for a long time and GitHub recently introduced the concept of Actions. There are many other tools like Jenkins, Travis etc.
There are a few articles on CI/CD on this blog as well.