Matthew McCullough and Tim Berglund, authors of the O'Reilly Git Master Class videos will introduce you to the very edges of Git's capabilities. There are plenty of "Getting Started with Git" sessions on the web, but we'd like to take 40 minutes of your time in an entirely different direction. These 40 minutes will primarily be live coding with a few diagrams for reference. We'll show you how Git reaches farther than any other version control system to provide capabilities for both the novice and the master craftsperson.
- EXPLAIN: Commits are a mutable journal of changes
- DEMO: Edit an interactive commit, then cherry-pick in a foreign change
git rebase -i STARTPOINT
- DEMO: Autosquash, fixup (Git 1.7.4)
- Squash a commit?
- Use the special commit message that triggers autosquash
- First demo the branch-cleanup type, then the interactive commit-cleanup type
git checkout FEATUREBRANCH; git rebase master;
- EXPLAIN: Local journal of changes
- This is local to your repo
- Doesn't travel with clones
- Defaults to 30 day expiration
- Can force the expiration, but why?
- Simple execution
git reflog
git reflog show HEAD
git reflog show master
git log -g
git log -g --date=relative
git log -g --abbrev-commit --pretty=oneline
- Uses revision syntax
- Revision Syntax
git show "master@{one day ago}"
- But you'll have to quote it because of the spaces
git show master@{one.day.ago}
- Dots can replace spaces so this doesn't have to be quoted
git show HEAD@{2}
- Relative position changes after each new command
- Can delete an entry, but rare to do it
git reflog delete HEAD@{3}
- Mostly just let it keep tracking
- What can you do with a ref?
- show
- cherry-pick
- merge
- checkout
- reset --hard
- DEMO: Undoing an undo
- Why would you use reflog?
- Add code
- Reset it away
- Bring it back
- Visualize all commits (including orphans)
gitk --all
- All branches
- Includes the stash
gitk --all
git reflog | cut -c1-7``git reflog
git reflog | cut -c1-7
- Then routing all those commits to gitk
- DEMO
git add . -p
- Add two methods to a file, but add them in hunks with -p
- File both in and out of staging area. How is this possible?
- DEMO: Rename a file and notice how it is still tracked
mv FILE1 PATH2/FILE2
git status
git add .
git add -A .
git log
git log --stat
git log --stat -M
git log --stat -C
- EXPLAIN: Similarity Index
- DEMO: Renames picked up even when origin commit didn't (no metadata for renames)
- DEMO:
git log -M --stat
- http://www.kernel.org/pub/software/scm/git/docs/git-log.html
- Visualize history showing renames
- Make a copy of a file between two directories. Do this in its own commit.
git log --stat -C
- and if in a separate commit
git log --stat --find-copies-harder
- Move a big chunk of a file (a big method) from one package to another, see it show up as a move
- Have a method with a bunch of printlns of poetry
- Make sure you're doing this on a branch
git blame FILENAME
- Show how the file came to be
git blame --date=short FILENAME
- Shorten the date
git blame -e FILENAME
- Show email addresses, not names
git blame -M FILENAME
- Show renames
git blame -C FILENAME
- Show copies or renames
git blame src/main/groovy/org/gittraining/Person.groovy -e --date=short
- Show the composition of a file in our sample project
-
--check
Warn if changes introduce trailing whitespace or an indent that uses a space before a tab. Exits with non-zero status if problems are found. Not compatible with --exit-code. -
-M[<n>]
--find-renames[=<n>]
If generating diffs, detect and report renames for each commit. For following files across renames while traversing history, see --follow. If n is specified, it is a is a threshold on the similarity index (i.e. amount of addition/deletions compared to the file’s size). For example, -M90% means git should consider a delete/add pair to be a rename if more than 90% of the file hasn’t changed. -
-C[<n>]
--find-copies[=<n>]
Detect copies as well as renames. See also --find-copies-harder. If n is specified, it has the same meaning as for -M. -
--find-copies-harder
For performance reasons, by default, -C option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large projects, so use it with caution. Giving more than one -C option has the same effect. -
-l<num>
The -M and -C options require O(n^2) processing time where n is the number of potential rename/copy targets. This option prevents rename/copy detection from running if the number of rename/copy targets exceeds the specified number. -
--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]]
Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, …) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.git log --diff-filter=A --stat
git log --diff-filter=M --stat
git log --diff-filter=D --stat
git log --diff-filter=D --stat -S "Person"
-
-S<string>
Look for differences that introduce or remove an instance of . Note that this is different than the string simply appearing in diff output; see the pickaxe entry in gitdiffcore(7) for more details.- git grep TEST_PERSON_NAME
- git log -S "TEST_PERSON_NAME"
- git log -S "TEST_PERSON_NAME" --pickaxe-all
-
-G<regex>
Look for differences whose added or removed line matches the given .- git log -G"set[a-zA-Z]+(" -p
-
--pickaxe-all
When -S or -G finds a change, show all the changes in that changeset, not just the files that contain the change in . -
--pickaxe-regex
Make the not a plain string but an extended POSIX regex to match.`