Git
Contents
Concepts
The main git objects are commits, trees and blobs. A git repository (repo) is a list of commits. A commit consists of a tree which in turn consists of blobs.
find ./.git/object -type f | sort
Each object is referenced by first 6-7 digits/letters of it's hash. The directory name under .git/object is part of the hash name. For instance
./.git/objects/46/3c1628ca10b51cab62ef3983f9e15119db56bc // hash is 463c16...
View the type of object using:
git cat-file -t <hash> // outputs blob, tree or commit
blobs
A blob is the SHA1 hash of the file contents.
git hash-object <filename|dirname>
git cat-file blob <blob_hash> // outputs file contents
git ls-files
trees
A tree is a collection of blobs
git ls-tree [-r] <commit_hash> // lists the blobs and sub-trees (-r recurses into subtrees) in the tree associated with commit_hash
commits
A commit is a snapshot of a working tree at some point in time.
HEAD defines what's currently checked out.
git rev-parse HEAD // outputs the hash of HEAD
git rev-list --all <--header> // list all commits in all branches --header for details about commit
git rev-list --max-count=2 <commit> // list the commit and it's parent
branch
A branch is a named reference to a commit.
git branch -v // lists branches in repository
git branch b1 // creates a new branch called b1
git checkout b1 // switches to branch b1
If you checkout a previous commit (which isn't a branch), make some changes and commit, that commit is considered detached from HEAD and will be lost unless you convert that commit to a branch:
git checkout -b b11
git show-branch
config
git config -l
git config --global user.name "Firstname Lastname"
git config --global user.email "email@gmail.com"
git config --global github.user github_username
git config --global github.token <token>
git config --global --unset credential.helper
github config
ssh-keygen -t rsa -C 'email' pwd
// Copy contents of id_rsa.pub to github
mv ~/.ssh/id_rsa ~/.ssh/github_rsa
mv ~/.ssh/id_rsa.pub ~/.ssh/github_rsa.pub
ssh-agent s
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/github_rsa
ssh -T git@githhub.com
workflow
git init [project-name] OR
cd directory
git init
git status
git diff
git diff --staged
git diff HEAD
git diff --color-words
Typical workflows always begin with a branch, no matter how small or grand the level of effort might be or the number of commits involved.
git branch // list branches, identify current branch
git branch [name] // create a new branch from current branch
git checkout [name] // switch to a different branch
git branch -m [current-name] [new-name] // rename any branch
git branch -d [name] // delete a *reachable* branch
git branch -D [name] // delete whether or not reachable
git merge [branch] // the final step to bringing the history of a branch into the current one is performed by merging it. Integrate history of specified branch into current one
git add <filename> // -u adds all files which have been updated
git add .
git add -u // update already tracked files
git reset <filename> // undoes add for single file
git reset // unstages all files which have been added
git commit -m "message"
git remote add origin git@github.com:github-user/repo.git
git push <origin> <master> // origin is remote repo master branch
Can include some more changes to previous commit.
git add -u
git commit --amend
Can (force) push amended commit to remote.
git push -f fork [branch]
rebase
git checkout b1
git rebase <commit_hash> // rebases the point where b1 branches to <commit_hash>
stash
git stash // same as "git stash save" stashes away changes without adding to index or committing
git stash save "message" //
git stash list // lists blobs in stash
git apply|pop <stash_ref>// pops
git diff --name-only da8152d 2032f7 // get changed filenames between 2 commits
git diff da8152d 2032f7 -- filename // get diffs between same file across 2 commits
git diff stash@{0}^1 stash@{0} -- <filename> // diff between stash and stash's parent (commit at which changes were stashed away)
git diff stash@{0}^! -- <filename> // cryptic version of above
git checkout stash@{0} -- <filename> // checkout single file out of stash
git show stash@{0}:<full filename> > <newfile> // save file from stash as new file
git show stash@{0}:./<relative filename> > <newfile> // same as above
git rm -r --cached <dir> //removes from git index - doesn't delete from file system
git rm -r -n dir/ // -n to only simulate -r for recursive removal. doesn't delete from file system
git clean dir/ // deletes from file system altogether
log
git log
git log -- <filename> // lists commits with changes to a file
git ref log // git can look back at the history of each commit to see when a change took place, who made the change, or what the change contained. Some simple option flag additions to the log command can make the output more concise.
git log --oneline // simple commit summaries
git log --patch --color-words // if displaying the full contents of the change and word-level comparisons are helpful, there are option switches for that too. Option switches common with `diff`
reset
git reset --soft HEAD^
git reset --hard // get rid of all changes made since last commit / checkout - use sparingly
git reset --hard <commit> // Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.
git reset HEAD <file>... // unstages <file>
git checkout -- <file> // re-instates <file> after git rm <file>, i.e. discards changes in working directory, the -- is merely a separator
Following allows splitting of an ammended commit into 2 separate commits.
git reset --soft HEAD@{1}
git commit -C HEAD@{1}
filter-branch
may be used to remove a file and all its history from index. Deletes file from working directory and edits/renames commit hashes and tags. Useful to remove files with sensitive information inadvertently added to repo.
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch run_confo_server.sh" --prune-empty --tag-name-filter cat -- --all
syncing with upstream
git clone https://github.com/tortuoise/pelican-themes
git remote -v //lists remote repos
* origin https://github.com/tortuoise/pelican-themes (fetch)
* origin https://github.com/tortuoise/pelican-themes (push)
git remote add upstream https://github.com/getpelican/pelican-themes.git
* upstream https://github.com/getpelican/pelican-themes.git (fetch)
* upstream https://github.com/getpelican/pelican-themes.git (push)
git fetch upstream
git checkout master // presumably origin master
git reset --hard //get rid of all local uncommitted changes
git merge upstream/master //merges with upstream/master
git push origin master //pushes origin/master
subtree
git subtree add --prefix=_vendor/github.com/gohugoio/gohugoioTheme/ git@github.com:/gohugoio/gohugoioTheme.git --squash
modules
gothas
Error encountered while cloning:
git clone https://github.com/hashicorp/vault
error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was received.
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
package github.com/hashicorp/vault: exit status 128
For more verbose output try:
GIT_CURL_VERBOSE=1 git clone https://github.com/hashicorp/vault
* GnuTLS recv error (-110): The TLS connection was non-properly terminated.816/103039), 19.32 MiB | 1.38 MiB/s
* stopped the pause stream!
* Closing connection 0
error: RPC failed; curl 56 GnuTLS recv error (-110): The TLS connection was non-properly terminated.
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
Try the following before re-cloning:
git config --global http.postBuffer 1048576000
The below will clone the master
branch. See ref to pull other branches.
mkdir -p $GOPATH/src/github.com/hashicorp
cd $GOPATH/src/github.com/hashicorp
git clone --depth 1
cd vault
git fetch --unshallow
git pull --all