git command line documentation
Table of Contents
IDE vs Shell
So far I was not happy with all the IDEs (Rstudio/Gitkraken/Github desktop) that I have tested. They provide some convenient shortcuts but in the end they tended to screw things up for me. That is why I am writing this documentation.
Advantages of IDEs
IDEs are much better at visualizing the branches and the commits. They are also much better for resolving merge conflicts (gitkraken).
Disadvantages of IDEs
You are always missing a functionality that makes you switch to the Shell. It is better to be literate with the shell commands all together to speed up your workflow.
The git repository
The git repository is your project folder, it contains some hidden files and folders that are used by git to track your commits and the branches. If you run git and open your repository you can set the folder to mirror commits or branches. This will actually change the files that you can find with your system explorer.
Introduce yourself
git config --global user.name 'Jennifer Bryan'
git config --global user.email 'jenny@stat.ubc.ca'
git config --global --list
Configure Proxy
git config --global http.proxy http://@173.15.80.153:8080
Setup local git without remote repos and RStudio
start with
git init
setup .gitignore (see instruction further down)
git add .
git commit -m 'message'
Setup local git repository with remote repository
starting with a local repository
- Setup a new project using the git option in Rstudio
- Create a new git repository on the github webpage
add the remote repository
git remote add origin https://github.com/user/repo.git
verify
git remote -v
first pull
to get README or .gitognore
pull --allow-unrelated-histories
first push
git push --set-upstream origin master
starting with a remote repository
open the directory you want to clone the repository in right click and select git bash here
git clone https://github.com/erblast/oetteR.git
.gitignore
The .gitignore
file contains a list of filenames that will be ignored and not and not tracked by git. When you are starting a git project it easy to skip this important file. It is however crucial to set it up before you start coding away. Once you are already deep in the project your workflow will be seriously disturbed when you keep having to do commits for file changes that you cannot control (for example thumbs.db
) or have to resolve merge conflicts in outputfiles of your code such as *.pdf
and *.html
files. You will find that adding filenames to .gitignore
that are already tracked will not work. You have to tediously add them manually in your git bash shell.
setting up .gitignore
- Creating your git project with Rstudio will already add some R/Rstudio files to
.gitignore
. - Here you can find a useful list of files to be added for R projects.
Creating .gitignore
from scratch
windows will not let you create files with a file name starting with ‘.’ use the windows command line tool
rename gitignore.txt .gitignore
Untracking files in hindsight
untracking a single file
git rm --cached [file_name]
untracking all files in a directory
git rm --cached inst/\*
untrack all files of a certain type
git rm -r --cached **/*.html
Navigating in the shell
switch between branches remember you create them only in the remote/origin repository
git checkout branch
what’s going on? Carefull the status is not always up to date. It seems to not check if the branch was updated from somewhere else than the current computer. It hapenned several times that the reply to the command implied that the current branch is up-to-date with the origin branch but then a pull command would still retrieve changes.
git status
Pull
Pull all
this would be nice to have but it DOES NOT WORK, it fetches from all branches but MERGES ONLY THE ACTIVE BRANCH.
git pull --all
pull active branch
git pull
pull and rebase
If you expect changes in you remote repository for your active branch (if your working on a collaborative project), you can rebase before/while pulling.
git pull --rebase
see http://kernowsoul.com/blog/2012/06/20/4-ways-to-avoid-merge-commits-in-git/, for setting this up permanently
commit
Use git status
to see a if there are any changes to commit. Commit as often as you like, give resonable namings to you commits. A commit will not work if you do not supply a commit message. Git will let you rollback to any commit you made. Always use the -m "text"
operator when calling git commit
, otherwise you will end up will display confusing commit screen.
git commit -m "enter message here"
if you see the confusing commit screen
you forgot to type -m "text"
**hit ESC
**
:wq
Undo commits, reset
Opt1: roll back to remote branch version
git reset --hard origin/workbranch
soft
and hard
parameter determines whether to keep the changes or not
~1
determines how many commits to go back in time
Opt2: undo last commit keep all changes
git reset --soft HEAD~1
Opt3: undo last commit discard all changes
git reset --hard HEAD~1
**Opt4: go back to specific commit **
git reset --hard 904jfd40f
Should I amend to previous commits?
No, dont do it. This only work if you have not pushed after your previous commit. If you have pushed you possibly get a merge conflict between origin and the local repository because the two commits are different. You can however fix this by rebasing the remote branch.
git rebase origin/master
Push
Push local commits to remote
git push
Overwrite remote version
git push origin branch_name -f
Rebase
rebase to update your work branch from master DO NOT FORGET MASTER in the command. Your branch will not fully merge and stuff will be missing and you will get merge conflicts. rebase active branch
git rebase master
Merge
Merging can be the most annoying part of using git, I tend to have merge conflicts all the time and they are annoying to resolve. I will have an extra section on this further down.
merge branch into master
git checkout master
git merge work_branch
Merge conflicts
Those are tedious to resolve and eat up time that could better be spent coding. If you have them use git status
to see whats wrong. Open the files with an editor and find the highlighted conflicting code and edit it. (remove the highlights inserted by git and keep the code that is correct). If there is an delete you can either add git add filename
or remove (git rm filename
). I think it is best to use this manual approach for a while and develope a disciplined git workflow that makes you avoid these all together. Then when you think you got it right switch to gitkraken to handle your merge conflicts.
Restore old commit versions
Checkout commit history of a certain branch
git log master
git revert 2342jk23l4jl2hg23k4j2h34
Managing branches
Create branch
git checkout -b [name_of_your_new_branch]
Delete branch
git branch -d [name_of_your_new_branch]
Accidently worked on the wrong branch
Sometimes you want to commit your changes and realize that you were working in master instead of your release or feature branch
git stash
git checkout branch123
git stash apply
Versioning
Your master
branch should always be the branch carrying the latest stable version. Branching off master
you have a release
branch which carries the newest developments. From this you branch off the other branches working on different aspects of the next release. Once the release
branch is stable it can be merged with master
Remove files from the history
Sometimes you might need to remove files from prior commits, either you carelessly commited large binary files which are bloating up your history, or some of the history contains sensitive information like passwords.
If you did not push to remote try undoing the commit using git reset --soft
This is an incredible hard thing to do. You will find lots of online ressources the most common being a command called filter-branch
. However removing files from git like this is a bit like rying to uninstall a program by removing the run.exe
from the installation folder. There will be a lot of clutter and references which will not be removed. I recommend the following in this case.
- remove the files you want to remove from your current branch
- create an on-disk copy of your repository
- delete your branch locally and from the remote
- create a new branch
- restore your branch by copying all files from your on-disk copy
- commit all changes
- push to remote
You cannot remove files from the master branch like this. Either if you do not need the history start a new repo, or figure out the filter-branch
command. This however needs some deeper knowledge on how git
acutally works.
Submodules
SUbmodules are great if you need to include code from another repository into your current repository that should be kept up to date.
git submodule add repo_adress
git submodule init
git submodule update
cd submodule
git checkout v1.0
Remove Submodules
If you dump another git repository into your currrent git repository because you might want to merge the two. Git will create a submodule that persits even if you delete all the git files from the repo that you want to fuze.
git rm --cached submodule_path # delete reference to submodule HEAD (no trailing slash)
git rm .gitmodules # if you have more than one submodules,
# you need to edit this file instead of deleting!
rm -rf submodule_path/.git # make sure you have backup!!
git add submodule_path # will add files instead of commit reference
git commit -m "remove submodule"
Release Tags
It is good practice to add a release tag after bumping up the version of your repository. It is the easiest to to this via the github website interface. However if you made a mistake and want to remove your current release because you made a typo github will not remove your release tag entirely but simply mark it as deleted which prevents you from creating a new tag with the same name. Thus we can use the following console command to delete it completely (source).
# delete local tag '12345'
git tag -d 12345
# delete remote tag '12345' (eg, GitHub version too)
git push origin :refs/tags/12345