- Introduce git workflow
- Show what git can do, but not in detail
- The Three States, Most Important Concept
- working directory (anything outside .git)
- staging area (a.k.a index -- .git/index)
- git repository (.git)
- References
- ancestry reference
HEAD^{,1,2}HEAD~{,1,2,...}- even more fancy --
HEAD~3^2
- (@) reflog, can help with retrieving lost commits --
HEAD@{<n>} - (@)
<branch1>..<branch2> - (@)
<branch1>...<branch2>
- ancestry reference
- Branch
- Workflow
- Alias
git config --global alias.st statusecho '[alias] st = status' << ~/.gitconfig
- Color
git config --global color.status auto- also check
color.{branch,diff,interactive} auto
- Log
git log --format=oneline --graphgit log --allgit log -p- even better:
git help log<CR>/PRETTY FORMATSor http://progit.org/book/ch2-3.html
- Commit early, commit often.
- Always know where you are --
statusandlog
- No need. Code, add, commit, push. Nothing special.
- Try to make your commit atomic and reasonable.
- Rewrite history if needed.
- Advanced:
- Feature branch with merge --no-ff: good for rollback but bad for bisect and blame
- Parallel development using branch and merge.
- Add
- add new file
- add new empty folder --
touch .gitkeeper - add new change
- Diff
git diffgit diff {--cache,<ref>}git diff --checkfor trailing whitespace (optional, better to setup your editor)
- Commit
git commit -mgit commit -amgit commit --amend{, -C HEAD}- commit guidelines http://progit.org/book/ch5-2.html
- start with a single line that’s no more than about 50 characters and that describes the changeset concisely
- followed by a blank line, followed by a more detailed explanation
- explain your motivation for the change and contrast its implementation with previous behaviour
- use commands like 'add something' instead of 'I added something'
- Revert
- unstage --
git reset HEAD <file> - discard --
git checkout -- <file> - revert commit --
git revert <hash>orgit revert <hash1>..<hash2>
- unstage --
- Show
git show <hash>:<path_to_file>
- Ignore Sample File
- ./.gitignore vs ~/.gitignore
git rm --cached <file>orgit rm --cached -r <folder>
- Remote
- remote
git push {, -f}git pull
- Advanced
- branch
git branch <new-branch>git checkout -b <new-branch>- remove local branch --
git branch -d <branch> - remove remote branch --
git push origin :<branch>
- merge
- resolve conflict
- if status is fine then to 5 else to 2
- search for
<<<<<<< - (maybe) communication
- add (again), to 1
- commit
git merge --no-commitgit merge --no-ff
- resolve conflict
- branch
- Use branch
- Public branch(master) is atomic, test-passed and deployable
- Never develop on public branch
- Private branch == draft
"Great books aren’t written– they’re rewritten." Michael Crichton
- To work on a new feature, create a descriptively named feature branch off of master.
- Commit to that branch locally and regularly push your work to the same named branch on the server. (Push to server is optional: up to you)
- When you finish that feature, rewrite commit history using reset/rebase/squash or amend to make every commit atomic and reasonable, remove all checkpoint commit and rebase onto master.
- Alternative, use
git merge --squashto generate only-one commit. - Fast-forward merge that feature branch from master branch and push to server.
- Remove remote and local branch.
- For fixing bugs, you may want to simplify the process using auto rebase. (optional)
- Using branch, parallel developing, good for hotfix.
- Clean, linear commit history, no merge commit, no checkpoint commit.
- Every commit is atomic and well documented with commit message, good for
bisectand code review. - Every commit is deployable, good for rollback.
- Switch Branch
git checkout <branch>
- Add
git add -igit add -p
- Diff
git diff --stagedgit diff <ref1>..<ref2>orgit diff <ref1> <ref2>git diff <ref1>...<ref2>- (@)
git merge-base <branch1> <branch2>
- Reset
git reset {--soft,--hard} <ref>
- Rebase
git rebase {,-i}- pick, edit, squash, reword, fixup
- remove, reorder
- split
git rebase {--abord,--continue}- never rebase public branch
- (@)
git rebase --onto <newbase> <upstream> <branch> - (@)
filter-branch- remove binary files in history
git filter-branch --tree-filter 'rm -f path/to/file.bin' HEAD
- remove binary files in history
- Fetch
pull==fetch+mergefetch+rebasegit pull --rebase
- Auto Rebase
git config branch.<branch>.rebase truegit config --global branch.autosetuprebase always
- Stash, WIP
git stash {,save <name>,save --patch <name>}git stash listgit stash {apply,apply --index,pop,clear,drop}- (@)
git stash branch
- Remove Untracked Files
rm ./*git checkout .
- Submodule
- (@) add, init, update
- (@) alternative: subtree merging
- Blame
git blame -L <from>,<to> path/to/file- ignore whitespace --
git blame -w
- Binary Search
git bisect startgit bisect {good/bad}orgit bisect run <path/to/script>git bisect reset
- Retrieve 'Lost' Commits
git cherry-pick <reflog>
- Shortlog
git log --pretty=short {filter} | git shortlog
- Garbage Collection
git gc
Open project means large public projects, including all kinds of software engineering. I searched for article about this kind of workflow but didn't get a perfect answer. So below is just my personal opinion, may be unrealistic and need improvement for sure. I'm not experienced in this workflow.
- Remote collaboration is possible.
- Support multipul release version.
- Puclic branch including develop, master(or current) and releases.
- Merge reviewed pull request into develop.
- Create new branch for each release off of develop and commit for release meta data.
- Merge into master and develop and tag on master.
- Hotfix commit in release branch and cherry-pick into develop (and other later release branch if necessary), fast forward merge into master and tag.
- Patch
git format-patch <target-ref>
- Apply
git apply {,--check } <patch-file>am==apply+commit
- Cherry-Pick
git cherry-pick <ref>
- Tag
- Archive
- check
git help archiveexamples
- check
- Shortlog