Skip to content

Instantly share code, notes, and snippets.

@PeterHajdu
Created April 4, 2012 09:49
Show Gist options
  • Save PeterHajdu/2300041 to your computer and use it in GitHub Desktop.
Save PeterHajdu/2300041 to your computer and use it in GitHub Desktop.
Some notes on git
1. distributed <-> centralized
2. cloning / initing ( let's start with a repo with some ruby code )
3. recording changes:
* git status (working tree/directory status) / git log
* the three states ( working directory, staging area, repository )
* file status / lifecycle of a file: untracked, unmodified, modified, staged
* status -> add -> status -> modify -> add -> status -> commit
* introduce yourself -> commit -> status -> log
* commit -a ( easy )
* deleting:
- from staging: git reset HEAD <path>
- from working tree: git checkout <path>
* more investigating commands:
- git diff, git diff --staged
- git show <hash> | shows info about objects/references
* push one at a time
* resolv conflict
* check merges at the end ( git log --graph )
* git fetch/rebase
Branching:
# list branches
$ git branch -a
# create a branch
$ git branch <branch name>
# go to a branch
$ git checkout <branch name>
# deleting branch
$ git branch -d <branch name>
# branches merged already
$ git branch --merged
$ git branch --no-merged
# tracking branches
$ git checkout --track <remotename>/<remote branch name>
# deleting remote branches
$ git push <remote> :<branch name>
# rebasing
$ git rebase <base branch> <topic branch>
Reset:
# manipulating the three trees: HEAD, index, working directory
$ git reset --soft <hash> # moves the ref pointed to by HEAD to the specified point
$ git reset --mixed <hash> # updates the index as well to the state of the new point
$ git reset --hard <hash> # updates the working directory!
$ git reset [ opts ] <path> # simply skips the 1. step, without a commit hash it unstages a file
# how to fast squash a few commits
$ git reset --soft HEAD~N; git commit # move the HEAD back N commits. The index still shows the last state, so the commit will record all changes to one commit. Awesome.
Checkout:
$ git checkout <branch name>
# Modifies only HEAD to point to a certain place, not the reference pointed to by HEAD.
$ git checkout <hash/branch> <path>
# will not modify HEAD, only working directory and index, just like git reset --hard
Interesting:
$ git pull-request
$ git format-patch
$ git notes add <point>
Bisect:
# create new branch
$ git bisect start
$ git bisect bad
$ git bisect good <commit hash of working code>
# use bad and good as you like
Tagging:
# List tags:
$ git tag
# Creating lightweight tags:
$ git tag <tag name>
# Creating annotated tags:
$ git tag -a <tag name> -m <comment>
# Creating signed tags:
$ git tag -s -u <key id> <tag name> -m <comment>
# push tags to remote:
$ git push <remote name> <tagname>
$ git push <remote name> --tags #share all tags
Plumbing:
#
# Objects
#
- git hash-object | compute object ID and optionally create blob
$ echo 'test content' | git hash-object -w --stdin
$ git hash-object -w <filename> | ( only content is saved )
- git cat-file | provide information for repo objects
$ git cat-file -p <hash> | pretty print
$ git cat-file -t <hash> | object type
$ git cat-file -p master^{tree} | prints the last commits base tree object
- git update-index | register file contents to the working tree in the staging area
$ git update-index --add --cacheinfo 100644 <full hash of blob> <name of file> | puts it only in the index, not in the working area
- git write-tree | create a tree object from the current staging area
$ git write-tree
- git read-tree | read a tree object from the repository to the staging area
$ git read-tree --prefix <directory name> <hash of tree object>
- git commit-tree | create a new commit object
$ echo "first commit" | git commit-tree <tree hash> -> commit comment from stdin
$ echo "second commit" | git commit-tree -p <parent commit hash> <tree hash>
$ git log <commit hash> | log from the commit specified with the hash
#
# References
#
-create a head reference for the master branch
$ echo <commit hash> > .git/refs/heads/maste | shit this is awesome
# now try the git log :D Awesome
#don't do this by hand!
$ git update-ref refs/heads/master <commit hash> #( did the same... )
THIS IS A BRANCH! DONE! A reference to the latest commit! Awesome!
Let's create another branch! ...
.git/HEAD is just a reference to refs/heads/master or something like that
# git checkout test would modify it to ->ref: refs/heads/test
# don't edit it by hand!
$ git symbolic-ref HEAD | to show
$ git symbolic-ref HEAD refs/heads/test | to set it to test
# tag is a reference which points to the same object in all it's life
#simple tag:
$ git update-ref refs/tags/<whatever> <object hash>
#annotated tag: creates a simple ref to the created annotated tag object in the repository
$ git tag -s <tagname> <object hash>
$ git tag -u <keyid> <tagname> <object hash>
# can point to every single object, it doesn't have to be a commit
# remotes: simple reference showing the commit hash of the last known head of the remote
#
# Packfiles
#
# after git gc or pushing to remotes
$ git verify-pack -v <path to pack.idx file>
#
# Maintenance
#
$ git reflog | show HEAD changes for some time
$ git reflog master@{2.days.ago} | guess :D
$ git log -g | same but shows more output
$ git fsck --full | shows objects not pointed to by other objects
#
# Removing objects
#
#pfff:
$ git rev-list --objects --all | grep
$ git log --pretty=oneline -- git.tbz2
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch git.tbz2' -- 6df7640^..
$ rm -Rf .git/refs/original
$ rm -Rf .git/logs/
$ git gc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment