Git ======================================== (2019) The [Pro Git](https://git-scm.com/book/en/v2/) book is very helpful. Its authors, Scott Chacon and Ben Straub, generously publish it under a Creative Commons license. Git is a distributed version control system. Branching and merging is far easier than with traditional VCS's. $ man git $ man gittutorial $ man git-help $ git help $ git help [commit add etc] Create a new repo: $ cd myproject $ git init $ git add . $ git status $ git commit -em "Initial import." Changes are added to a cache/staging area before being committed. Files can be added individually before being committed as a second step, or the add-all-commit can be done as one step: $ git add foo.txt $ git status $ git commit $ git commit -aem 'Fixed caching (issue 4321).' Keep the first line of the commit message short — fewer than fifty characters. Include an additional details in subsequent paragraphs separated by a blank line. The `-e` flag invokes the editor to compose a commit message: $ git commit -e Pull the diffs for the staged changes directly into the commit message editor: $ git commit -v `git-commit(1)` says: > Note that this diff output doesn’t have its lines prefixed with #. This diff will not be a part of the commit message. **Best of all:** $ git commit -ve Unstage a file added to the cache but not yet committed: $ git rm --cached foo.txt Revert a changed or deleted file: $ git checkout -- foo.txt (A bare double-dash " -- " avoids ambiguity by separating options from a list of arguments.) Discard all local working changes: $ git reset --hard HEAD Remote Repositories ---------------------------------------- Create a remote origin repo: $ ssh example.com mkdir ~/repo/myproject $ ssh example.com git init --bare ~/repo/myproject $ cd myproject $ git remote add origin ssh://example.com/~/repo/myproject $ git push --set-upstream origin master At some point `--set-upstream` stopped working. Instead: $ git branch --set-upstream-to=origin/master master Clone a remote repo: $ git clone ssh://example.com/project Pull updates from a remote: $ git pull [remote] Additional remotes: $ git remote -v $ git remote add mynewremote ssh://example.com/~/foo $ git push mynewremote Add Github as an additional remote: $ curl -u 'pgorman' https://api.github.com/user/repos -d '{"name":"myproject","description":"This is my project."}' $ git remote add github https://github.com/pgorman/myproject.git $ git remote -v $ git push github master Show status of a particular remote: $ git remote show Unlink a remote repository: $ git remote remove github Reviewing Logs and Comparing Changes ---------------------------------------- ``` $ git log --stat commit 47e95939843d35906c26032338727f98a901f7a2 Author: Paul Gorman Date: Thu Aug 9 22:04:56 2018 -0400 Spelling. zerapis.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit c11ff2d1c0d1fe0f0f6e0634c503b0a917c8834e Author: Paul Gorman Date: Thu Aug 9 21:10:31 2018 -0400 Moving to markdown. zerapis.txt | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) $ git log commit 47e95939843d35906c26032338727f98a901f7a2 Author: Paul Gorman Date: Thu Aug 9 22:04:56 2018 -0400 Spelling. commit c11ff2d1c0d1fe0f0f6e0634c503b0a917c8834e Author: Paul Gorman Date: Thu Aug 9 21:10:31 2018 -0400 Moving to markdown. $ git log --pretty=oneline 47e95939843d35906c26032338727f98a901f7a2 Spelling. c11ff2d1c0d1fe0f0f6e0634c503b0a917c8834e Moving to markdown. $ git log --all --graph --oneline --decorate * 2a33954 (HEAD -> master, origin/master) Server gives each game an ID. * 6d73f85 Draw board by JS. * 817fe58 Started Go web server. * f579205 Tinkering with UI. * 3aa1cd4 Visually indicate selected tool. * ca1b186 Client-side stuff works. * dcd844c Initial import. ``` Review commit logs, and compare two commits: $ git log --stat [master origin foo etc] $ git diff e274 47c9 Commits are identified by 40-hexadigit hashes. We can refer to a commit by the first few characters of the hash, where there's no ambiguity. Show changes over time for a particular file: $ git log -p myfile Search when a particular string changed (a.k.a., Git's "pickaxe" option): $ git log -S foobar Diff changed files have not yet been staged/cached: $ git diff Diff staged/cached files: $ git diff --cached Diff HEAD with the previous commit: $ git diff @~..@ or: $ git diff HEAD\^ HEAD Branches and Merging ---------------------------------------- Branches are named. The default branch is 'master'. The tag 'HEAD' refers to the tip (latest commit) of the current branch. $ git branch $ git branch --list $ git branch testbranch $ git checkout testbrach $ git checkout master $ git branch --delete testbranch If we want to switch branches without committing the work-in-progress in our current branch: $ git stash $ git stash list Restore stashed files once we switch back to the original work-in-progress brach: $ git stash list $ git stash apply [stash@{n}] Merge a branch back into master: $ git checkout master $ git merge testbranch Resolve merge conflicts: $ git mergetool or specify the tool: $ git mergetool --tool=gvimdiff Config Files ---------------------------------------- `~/.gitconfig` has per-user settings. `/etc/gitconfig` is global for the box. Show effective settings: $ git config --list --show-origin `~/repo/myproject/.git/config` has per-project settings. `~/repo/myproject/.gitignore` sets per-project list of files to ignore. Wildcards can be used. Reviewing a Github merge request ---------------------------------------- https://help.github.com/articles/checking-out-pull-requests-locally/ 1. Under the repository name, click Pull requests. 2. Select a pull request from the list of pull requests. 3. Near the bottom of the pull request, in the merge box, click "command line instructions". Follow the instructions. For example: Check out a new branch and test the changes: git checkout -b makhidkarun-master master git pull https://github.com/makhidkarun/travellercharactergenerator.git master Merge the changes and update GitHub: git checkout master git merge --no-ff makhidkarun-master git push github master Tagging ---------------------------------------- https://git-scm.com/book/en/v2/Git-Basics-Tagging Tags mark specific points in a repo's history as important. Use this to label a particular commit as a major version (v2.0), for example. ``` $ git tag v1.0 v2.0 $ git tag -l "v1.8.5*" v1.8.5 v1.8.5-rc0 v1.8.5-rc1 v1.8.5-rc2 v1.8.5-rc3 v1.8.5.1 v1.8.5.2 v1.8.5.3 v1.8.5.4 v1.8.5.5 $ git tag -a v2.0 -m "Release 2.0 finalizes the new network features." ``` Or, retroactively tag a previous commit: ``` $ git tag -a v1.2 9fceb02 ``` By default, git does not push tags to remote servers. Push one or all tags like: ``` $ git push origin v1.5 $ git push origin --tags ``` Not Covered ---------------------------------------- rebase, tags, blame, pickaxe, bisect Links ---------------------------------------- - http://git-scm.com/book/en/v2 - http://ohshitgit.com/ - https://bitbucket.org/BitPusher16/dotfiles/raw/49a01d929dcaebcca68bbb1859b4ac1aea93b073/refs/git/git_examples.sh - https://girliemac.com/blog/2017/12/26/git-purr/