Git usage
From wikinotes
basics
branches
## branches git branch f-mynewfeature ## create branch git checkout f-mynewfeature ## checkout branch git checkout HEAD --force ## checkout branch, git checkout $(git merge-base @ origin/HEAD) # checkout commit before branch startfiles
## files git add path/to/file ## add file to branch's stage git add --all :/ ## add all changed files to branch's stage git checkout HEAD path/to/file ## checkout a file from an older commit git checkout f-mybranch path/to/file ## checkout a file from an older commit git commit ## commit current stage to branch git commit --amend ## add current changes to last commit git rm path/to/file ## remove file from git git mv path/to/file path/to/other ## move a file (history continues to track file)stage
git checkout HEAD path/to/file git checkout f-mynewfeature path/to/file git add path/to/file git add --all :/ git commit git push git diff HEAD..HEAD~2 path/to/file git clean -fd # remove untracked files git stash git stash pop git stash listlog
## log git log git log --oneline git log --abbrev-commit # use short commit hashes git log --grep 'Deprecated' # search commit messages for 'Deprecated' git log -G 'def foo' # search commit diffs for changes involving 'def foo' git log /path/to/file git log -L${start_ln},${end_ln}:${filepath} # view log for all changes to this selection of lines git log -L${function}:${filepath} git log --all --full-history -- ${filepath} # view log for a deleted filestatus
## status git status git diffclone
git clone https://github/blah.git git clone ssh://git@server:8888/path/to/repo git clone ssh://server:/path/to/repo ## NOTE: if you have configured your ~/.ssh/config with all info, you only need to specify machine git clone file:////home/you/src git clone --depth=1 https://github.com/user/blah # clone only latest checkoutsubmodules
## Adding a submodule to a project cd ../my_git_project git submodule add ssh://gitbox:/home/git/_python/supercli git submodule update --init ## update (fetch changes) git submodule update --init ## deinit (clear dir, stop recording changes) git submodule deinit ## pull cd ../gitroot/mymodule git pull cd ../gitroot git submodule update --init --recursive ## pull all submodules for the first time. git submodule update <your submodule name> ## pull individual submodule git pull --recurse-submodules ## change remote set-url (untested) vim .gitmodules # remove your submodule git config --edit # remove your submodule git rm --cached your/submodule # remove your submodule's path git submodule syncmultiple urls for a submodule:
#### .git/modules/..submodule_name.../config [remote "origin"] url = ssh://user@box1:2222/path/to/repo url = ssh://user@box2:2222/path/to/other/repo ####patches
Create patch from unstaged changes
# in a repo with unstaged changes cd /path/to/projectroot git diff --binary > description.patch cd /path/to/other/projectroot git apply description.patchSquash all differences between branches into a patch
git merge needs_changes has_changes # VERY IMPORTANT! git checkout -b deleteme has_changes git reset --soft needs_changes git diff --binary HEAD > ~/description.patch git checkout -b recv_patch needs_changes git apply ~/description.patchsearch
# ========== # Searching # ========== git log \ -p \ # print diff -m \ # include merge commit diffs -G '\$\(document\)' \ # regex commit+diff --abbrev-commit \ # short commit hashes --name-only \ # when used with `-p`, only filenames are shown instead of full diffs git log -G "regex" # search commits, whose text, or diff contains this regex git log --abbrev-commit -p -m -G "regex" # seearch log, show diffs, (even commit diffs), matching regex git log --abbrev-commit -p -m -- file.txt # show commits/diffs for all commits related to file git rev-list --all | xargs git grep <regex> # search all changesets for keyword git grep <regex> $(git rev-list --max-count=50) # search last 50 changesets # show all commits involving file gitk --all --first-parent --remotes --reflog --author-date-order -- filename git log --all --first-parent --remotes --reflog --author-date-order -- filename # show all commits involving file, including diffs for merge commits for f in `git rev-list --all --first-parent --remotes --reflog --author-date-order -- your_filename.rb | tr '\n' ' '`; do echo "========\n$f\n========"; git show -m --color=always $f | cat ; done | less -Ri # ============ # Show Changes # ============ git show aaaaaaaa # show commit message/changes (except merges) git show -U 30 aaaaaaaa # show commit message/changes and 30 lines surrounding git diff aaaaaaaa^! # show changes (always works)tags
You can tag releases of your git repository with versions so that they are easy to revert.
Listing Tags
git tag # list all tags git tag -l '1.*' # list matching tagsCreating Tags
# create lightweight tag 1.1.1 git tag 1.1.1 # create annotated tag # (a real git commit, can be GPG signed, has commit message) git tag \ -a 1.1.1 \ -m "my released 1.1.1"Tag Info
git show 1.1.1 # print info about tag 1.1.1show
git show master:/path/to/file.rb # show file without changing branches git show 1.1.1 # show tag 1.1.1commits
git diff ${COMMIT}~ ${COMMIT} # show changes introduced by a commit (since commit before it) git rev-list -1 --before='2021-08-16T18:00:00' master # find commit(s) before a specific datetimediff
difftool
Pro tip, you can use vimdiff as a diff tool
git difftool --tool vimdiff2Within vim you can use:
1,20diffput
to put everything from line 1-20 into the other bufferdo
pull block from other sidedp
push block to other side
Advanced
filter-branch
Remove target file anywhere it is found in entire git history.
git filter-branch \ -f \ --index-filter 'git rm --cached --ignore-unmatch *.sql' git filter-branch \ -d /your/temp/workdir `# temporary working dir for filtered branch` \ --prune-empty `# delete commits that are now empty as result of oper` \ --index-filter `# executes command on every commit` \ "git rm --cached -f --ignore-unmatch oops.iso" \ --tag-name-filter cat `# rename tags (references to files) so history is consistent` \ -- --all `# run this on every commit in the entire git history`See
- https://stackoverflow.com/questions/2047465/how-can-i-delete-a-file-from-a-git-repository
- https://stackoverflow.com/questions/2100907/how-to-remove-delete-a-large-file-from-commit-history-in-git-repository
rebase
git log --nameonly origin/master..HEAD # count number of log entries. git rebase -i HEAD~3 # rebase last 3 commits (1-indexed)
- editor will open. Change letter in front of each commit to desired operation
- change commit, then
git rebase --continue
to continue working through commitsto split up a commit
git rebase -i HEAD~1 # 'e' in front of commit git reset HEAD^ # now git add, or use git-gui to add lines you want in your new commitsblame
git blame helps you find who wrote a section of a file, so you can ask them for details about how it works.
git blame filename # find last author to modify any line in file git blame filename -L 0,10 # find last author to modify lines 0-10revert
# before push # after push (revert branch) git revert HEAD~5..HEAD # revert everything from last 5x commits in single commit
Workflows
merge conflict
git merge ${BRANCH} git diff ORIG_HEAD MERGE_HEAD file.txt # show diff of conflict