Git¶
- Date
November 11, 2020
Contents
1 Learning Sources¶
The following YouTube videos were helpful:
Introduction to Git - Core Concepts (by David Mahler): https://youtu.be/uR6G2v_WsRA
Introduction to Git - Branching and Merging (by David Mahler): https://youtu.be/FyAAIHHClqI
Introduction to Git - Remotes (by David Mahler): https://youtu.be/Gg4bLk8cGNo
Rewriting Git History - Amend, Reword, Delete, Reorder, Squash and Split (by “The Modern Coder”): https://youtu.be/ElRzTuYln0M
Web resources
Git reference manual: https://git-scm.com/docs
Git Handbook (by GitHub): https://guides.github.com/introduction/git-handbook/
2 Basic concepts and terms:¶
Overall structure: working tree <-(checkout)-|-(add)-> **staging area** <-(reset)-|-(commit)-> history <-(fetch/pull)-|-(push)-> remote
difference: working tree <-> staging area <-> history
working tree is also called the workspace
staging area is also called as the index, cache, directory cache, current directory cache, staged files (ref). It is a single, large, binary file in
<baseOfRepo>/.git/index
, which LISTS all files in the current branch, their sha1 checksums, time stamps and the file name – it is NOT another directory with a copy of files in it.history is also called as the local repository. This is a hidden directory (
.git
) including anobjects
directory CONTAINING ALL versions of every file in the repo (local branches and copies of remote branches) as a compressed “blob” (Binary Large Object) file. (ref)HEAD
is the pointer to the working tree. To find where HEAD points to, runcat .git/HEAD
master
is the pointer to the local master branchdetached HEAD
is the situation whereHEAD
(current working tree) is notmaster
or with a branch name.WIP
means Work In Progress (stashing)origin
short name for the location of the remoteorigin/master
is called the remote tracking branch (what the master branch looks like atorigin
)upstream
: let A be a repository, B be a fork of A, C be a local clone of B. Then A is called the upstream of Cfetch
download remote to the local historypush
upload the local history to remotemerge
tag
specific points in a repository’s history as being important, eg. v1.0, v2.0, …branch
Local branches aren’t automatically synchronized to the remotes so we have to explicitly push the branches you want to share. (TODO: continue to Remote Branch)
3 .gitignore¶
The file .gitignore
lists files, per line, that should be ignored.
comments starts with
#
:# COMMENT
we can explicitly specify files,
.DS_Store
we can use regexp,
\*~
,\*.log
a whole folder is indicated by
<FOLDER>/
5 config¶
git config --global user.name "<NAME>"
git config -- global user.email "<NAME@EMAIL.ADDRESS>"
git config --local user.name "<NAME>"
git config -- local user.email "<NAME@EMAIL.ADDRESS>"
To list config:
git config --list
7 log¶
git log
git log -p
git log -- <FILE>
git log --all --decorate --oneline --graph
It’s convenient to alias this.
8 add: working tree -> staging area¶
git add FILE
FILE
can be a list of files, FILE1 FILE2 FILE3 ...
we can use regexp, for eg, S*
for all files starting with S
To add all modified files
git add .
10 commit: staging area -> history¶
git commit
To commit with a short commit message:
git commit -m "<SHORT COMMIT MESSAGE>"
To commit without any commit message:
git commit --no-edit
To amend the last commit:
git commit --amend
(This does changes the ID of the last commit. Amending works only for the latest commit.)
To commit without
11 add+commit: working tree -> staging area and history¶
git commit -a
nothing to specify after git rm
13 diff: staging area <-> history¶
git diff --staged
14 checkout: working tree <- staging area¶
git checkout -- <FILE>
To place HEAD (i.e., to retrieve) to the state <HASH>:
git checkout <HASH>
<HASH>
can be the first five characters
15 checkout: working tree and staging area <- history¶
git checkout <HASH> -- <FILE>
16 checkout branch¶
git chekout <BRANCH NAME>
17 reset: staging area <- history¶
git reset HEAD <FILE>
18 branch: list¶
To list all branches:
git branch
To list merged branches:
git branch --merged
To list local and remote branches:
git branch -a
To list remote tracking branches only:
git branch -r
19 branch: create new¶
To create a new branch from HEAD:
git branch <BRANCH NAME>
To create + checkout -> new branch:
git branch -b <BRANCH NAME>
20 branch: remove¶
git branch -d <BRANCH>
21 merge: HEAD -> master¶
To merge <BRANCH> into master:
git merge <BRANCH>
The response can be different depending on the strategy:
fast-forward
three-way (recursive)
In case of conflict, files with conflict get modified with diff contents. We can check and resolve these conflict by opening those files. When doing this, we also need to delete git markers.
After conflicts are resolved, do
git status
.Aborting the merge process will restore the original file contents:
git merge --abort
If all named commits are already ancestors of HEAD, git merge will exit early with the message “Already up to date.” This is the situation when we try to merge the same branch. In such a situation, differentiate two points by distinct branches, merge, and then remove the unnecessary branch name.
After merging with master
branch with another branch, <BRANCH>
to say, the branch <BRANCH>
that may not be necessary anymore is not automatically deleted. We have to this manually:
git branch -d <BRANCH>
22 restore¶
$ git checkout <branch> <filename>
will bring back <filename>
from <branch>
. This can be used when we want to restore a deleted or modified file.
23 Stash: save¶
To save working directory without staging:
git stash
To stash with comment:
git stash save "<comment>"
24 stash: list¶
To list all stashes:
git stash list
To list all stashes with changes:
git stash list -p
25 stash: apply¶
git stash apply
git stash apply <LABEL>
Here, <LABEL>
is the one given by stash list
27 remote: add/remove¶
To add a new remote:
git remote add origin <REMOTE REPOSITORY URL>
To add upstream:
git remote add upstream <UPSTREAM REPOSITORY URL>
To remove:
git remote remove <REMOTE NAME>
After modifying remote/upstream, run git remote -v
to verify.
28 remote: list¶
To list remotes (short names only):
git remote
To list remotes (short and full names only):
git remote
To list remotes verbosely:
git remote -v
29 fetch: local repository <- remote repository¶
git fetch origin
Note that this does not affect local/HEAD. We need to merge, eg. git merge origin/master
later.
git fetch upstream
To fetch and merge:
git pull <REMOTE> <BRANCH>
The error “fatal: refusing to merge unrelated histories” may occur when we try to merge/pull unrelated repositories together. For example, we might try to resume old project from scratch while wanting to keep the same GitHub repository. To resolve this:
git pull <REMOTE> <BRANCH> --allow-unrelated-histories
30 push: local repository -> remote repository¶
git push <REMOTE REPOSITORY: eg. origin> <LOCAL BRANCH: eg. master>
$ git push --set-upstream origin master
To https://...
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://...'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
hbshim@aleph:~/Dropbox/Workspace/math/build/html$ git push -f
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
$ git push -f
31 rebase¶
To “operate on” the last <n> commits back from HEAD:
git rebase -i HEAD~<n>
(-i
indicates “interactive”.)
Interactive commands:
reword
: edit commit messagedrop
: remove commit
We can also reorder commits by changing the order of the lines.
33 tag¶
To list tags,
git tag
To create an annotated tag named TAG
:
git tag -a <TAG> -m "<COMMENT>"
To see the data for the tag named TAG
git show <TAG>
To push the tag TAG
to the remote original
:
git push origin <TAG>
To push all tags to the remote original
:
git push origin --tags
To delete the tag TAG
:
git tag -d <TAG>
Caution: This does not remove TAG
from the remote.
To delete the tag TAG
from the remote original
:
git push origin --delete <TAG>
To checkout TAG
:
git checkout <TAG>
This will cause the “detached HEAD” state since what was checked out is merely a commit hash not a branch (even if there was branch tip pointing to the commit TAG
). We need to branch out to work on and modify the commit hash TAG
:
git checkout -b <BRANCH> <TAG>
git should respond with the message “Switched to a new branch <BRANCH>
.”