https://hs2010-git.github.io/adv/
A Git repository is just a bunch of objects.
An object is either a commit, a tree, or a blob (file).
Each commit points to a tree, parent commit(s), and has some metadata.
i.e. each commit is a snapshot of files, with some metadata and parent commit(s). That's it.
Commits form a directed acyclic graph.
Branches and tags (refs) are just pointers to commits.
The "current branch" is simply whatever is pointed to by the HEAD ref.
commit --amend
Amends the current commit (HEAD).
Other useful flags with this:--date
, --author
, --reset-author
rebase -i <base>
Interactive rebase onto base
.
p, pick <commit> = use commit
r, reword <commit> = use commit, but edit the commit message
e, edit <commit> = use commit, but stop for amending
s, squash <commit> = use commit, but meld into previous commit
f, fixup <commit> = like "squash", but discard this commit's log message
x, exec <command> = run command (the rest of the line) using shell
b, break = stop here (continue rebase later with 'git rebase --continue')
d, drop <commit> = remove commit
l, label <label> = label current HEAD with a name
t, reset <label> = reset HEAD to a label
m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
. create a merge commit using the original merge commit's
. message (or the oneline, if no original merge commit was
. specified). Use -c <commit> to reword the commit message.
rebase -i <base>
Exercises1dab2c
. (There are at least 2 ways of doing so.)cherry-pick
Pick commits and apply them on top of the current HEAD.
e362b5
.Sometimes, PRs are created with very messy histories.
Clean up the history of this PR.
A patch/diff file simply consists of the output of diff
, show
, etc.
You can send a file to someone else to apply.
apply
Apply a patch.
diff --git a/hello.c b/hello.c
index 896abe6..d8f149b 100644
--- a/hello.c
+++ b/hello.c
@@ -2,7 +2,7 @@
int main(int argc, char *argv[]) {
if (argc > 1) {
- printf("Hello %s!\n", argv[1]);
+ printf("Hello %s! You said %d more things.\n", argv[1], argc - 2);
} else {
printf("Hello uncertain worl\n");
}
format-patch <since / range>
Generate patches for multiple commits.
This is how one formats patches for the Linux kernel!
am
"Apply mail". This is how Linux kernel maintainers apply patches received on the mailing lists.
Apply the two patches in the repository.
You can get patches from a GitHub commit by just adding .patch
to the URL.
bisect
Binary search for a commit. Usually used to find the commit in which something broke.
Bisect the bisect
branch. Find the first commit that has "BROKEN" in file
.
Now bisect it automatically using bisect run
.
reflog
View a ref's log (i.e. the commits it has pointed to in the past).
Do some destructive operation e.g. commit --amend
. Use reflog
to restore your original commit.
filter-repo
Rewrite a repository.
Use filter-repo
to remove secret
from the repository entirely.
submodule
Include a repository within your current directory.
Add a submodule. Use any repository, or this if you can't think of any.
Make the submodule refer to a different commit.
worktree
Have multiple branches checked out at a time.
Check out the branch
branch as a separate worktree.
.git
layoutHEAD
: points to the active refindex
: the repository indexconfig
: repository-specific configurationobjects
, refs
, logs
: as per the nameMore information: gitrepository-layout(5)
gc
Optimise the repository and prune unused objects.
Add and commit a new file. Then (pretend it's an accident) reset the commit, expire the reflog, and gc
to prune the objects. Use cat-file
to verify the presence of the object.
update-index --add ...
write-tree
commit-tree
Feedback
https://bit.ly/hs2010-advgit-fb
Slides
https://hs2010-git.github.io/adv/