Version Control (Git) #
Lecture source: https://missing.csail.mit.edu/2020/version-control/
Get the detail content in your git commit (under the hood):
$ git cat-file -p <git_hash>
Get the git log in a graphed, linear way:
$ git log --all --graph --decorate [--oneline]
Resolve git merge conflict:
$ git mergetool
$ git add <your_files>
$ git merge --continue
Maintain the relationships betwen local and remote branches:
$ git branch --set-upstream-to=<remote name>/<remote branch>
# get the branch relations
$ git branch -vv
Clone only the lastest snapshot of a repository.
$ git clone --shallow <repo url>
An interactive interface for git add
:
$ git add -p
Get information for a particular commit:
$ git show <commit hash>
Exercises #
-
If you don’t have any past experience with Git, either try reading the first couple chapters of Pro Git or go through a tutorial like Learn Git Branching. As you’re working through it, relate Git commands to the data model.
Skip it.
-
Clone the repository for the class website.
-
Explore the version history by visualizing it as a graph.
$ git log --all --graph --decorate --oneline | head * 488e636 (HEAD -> master, origin/master, origin/HEAD) Merge pull request #187 from HtwoO/patch-1 |\ | * 90fe0de private key path is expected after -i of ssh client |/ * 9837d16 Merge branch 'soulrrrrr/soulr' |\ | * d8991dc Add <br> at the 'About the class' section. The 'Questions' title will move to the next line. |/ * b2c02c8 Merge pull request #178 from ChathurGudesa/master |\
-
Who was the last person to modify
README.md
? (Hint: usegit log
with an argument).
$ git log README.md | head commit 8010724516adc968765e8efd14991f262f0d0423 Author: Anish Athalye <[email protected]> Date: Tue Jul 27 08:29:08 2021 -0400 Separate build and links status commit 79d143ff650d59a2d69961b2c68d697096c0e8f4 Author: Anish Athalye <[email protected]> Date: Sat Dec 26 09:42:23 2020 -0500
Obviously, is Anish.
-
What was the commit message associated with the last modification to the
collections:
line of_config.yml
? (Hint: usegit blame
andgit show
).
$ git blame _config.yml | grep collections: a88b4eac (Anish Athalye 2020-01-17 15:26:30 -0500 18) collections:
We have blame the last editor of
collections:
line is Anish Athalye, and the commit hash isa88b4eac
. Now we can usegit show
with this commit hash to get the commit message.$ git show a88b4eac commit a88b4eac326483e29bdac5ee0a39b180948ae7fc Author: Anish Athalye <[email protected]> Date: Fri Jan 17 15:26:30 2020 -0500 Redo lectures as a collection
-
-
One common mistake when learning Git is to commit large files that should not be managed by Git or adding sensitive information. Try adding a file to a repository, making some commits and then deleting that file from history (you may want to look at this).
Init a new git workding directory first and make some commits.
$ mkdir git-remove $ cd git-remove $ git init $ echo 'some sensitive data' > sensitive $ git add sensitive; git commit -m '1st commit' [master (root-commit) 41f6bfe] 1st commit 1 file changed, 1 insertion(+) create mode 100644 sensitive $ echo 'another sensitive data' >> sensitive $ git add sensitive; git commit -m '2nd commit' [master 5d7bfa1] 2nd commit 1 file changed, 1 insertion(+) $ echo 'the final sensitive data' >> sensitive $ git add sensitive; git commit -m '3rd commit' [master fe28712] 3rd commit 1 file changed, 1 insertion(+) $ git log --all --graph --decorate --oneline * fe28712 (HEAD -> master) 3rd commit * 5d7bfa1 2nd commit * 41f6bfe 1st commit
So the
sensitive
file should be removed, try to use thegit filter-repo
tool to achieve this.$ git filter-repo --invert-paths --force --path sensitive Parsed 3 commits New history written in 0.03 seconds; now repacking/cleaning... Repacking your repo and cleaning out old unneeded objects Enumerating objects: 1, done. Counting objects: 100% (1/1), done. Writing objects: 100% (1/1), done. Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 Completely finished after 0.12 seconds.
Why use
--force
in here?Our repo has inited maually so it is not a “fresh clone”, there are more than one line in
.git/logs/HEAD
, so the--force
option is needed.Let’s check the
sensitive
file.$ ls -a . .. .git $ git log --all --graph --decorate --oneline
So we can see the
sensitive
file has gone in the current working directory and the git log is empty now, thesensitive
file not longer exists. -
Clone some repository from GitHub, and modify one of its existing files. What happens when you do
git stash
? What do you see when runninggit log --all --oneline
? Rungit stash pop
to undo what you did withgit stash
. In what scenario might this be useful?
$ git clone [email protected]:deb-sig/double-entry-generator.git some-test-repo Cloning into 'some-test-repo'... remote: Enumerating objects: 1159, done. remote: Counting objects: 100% (238/238), done. remote: Compressing objects: 100% (134/134), done. remote: Total 1159 (delta 144), reused 128 (delta 97), pack-reused 921 Receiving objects: 100% (1159/1159), 1.87 MiB | 1.33 MiB/s, done. Resolving deltas: 100% (419/419), done. $ vim README.md $ git diff diff --git a/README.md b/README.md index cf6b33b..3acaca6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +This is a line for git stage test. + # double-entry-generator
Then we make the changes stashed.
$ git stash Saved working directory and index state WIP on master: 6486dc0 fix two issues (#55) $ git log --all --oneline 438ac40 WIP on master: 6486dc0 fix two issues (#55) 191e798 index on master: 6486dc0 fix two issues (#55) 6486dc0 fix two issues (#55) ... 6a96eab feat: Update 5350856 Initial commit
The
git stash
makes temporary commits191e798
and438ac40
in this git log, and we can reveal some details for this commit bygit show
.$ git show 438ac40 | more commit 438ac4013e08d087d7858d1e773e5a9aa2038f04 Merge: 6486dc0 191e798 Author: Triple-Z <[email protected]> Date: Tue Mar 15 22:50:18 2022 +0800 WIP on master: 6486dc0 fix two issues (#55) diff --cc README.md index cf6b33b,cf6b33b..3acaca6 --- a/README.md +++ b/README.md @@@ -1,3 -1,3 +1,5 @@@ ++This is a line for git stage test. ++ # double-entry-generator
Recover the changes by
git stash pop
.$ git stash pop On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (438ac4013e08d087d7858d1e773e5a9aa2038f04)
See the git log again, and the two commits at the top before are gone.
$ git log --all --oneline | head -n 2 6486dc0 fix two issues (#55) a3d710f fix(goreleaser): build with git version info (#53)
-
Like many command line tools, Git provides a configuration file (or dotfile) called
~/.gitconfig
. Create an alias in~/.gitconfig
so that when you rungit graph
, you get the output ofgit log --all --graph --decorate --oneline
. Information about git aliases can be found here.
Add the following lines to the
~/.gitconfig
.[alias] graph = "log --all --graph --decorate --oneline"
Then run the
git graph
, magic happens.$ git graph * 6486dc0 (HEAD -> master, origin/master, origin/HEAD) fix two issues (#55) * a3d710f (tag: v1.5.0) fix(goreleaser): build with git version info (#53) ... * 6a96eab feat: Update * 5350856 Initial commit
-
You can define global ignore patterns in
~/.gitignore_global
after runninggit config --global core.excludesfile ~/.gitignore_global
. Do this, and set up your global gitignore file to ignore OS-specific or editor-specific temporary files, like.DS_Store
.
Set up the global gitignore to ignore
.DS_Store
.$ echo ".DS_Store" >> ~/.gitignore_global $ git config --global core.excludesfile ~/.gitignore_global
Check if it works.
$ touch .DS_Store $ ls -a . .. .DS_Store .git $ git status On branch master No commits yet nothing to commit (create/copy files and use "git add" to track)
-
Fork the repository for the class website, find a typo or some other improvement you can make, and submit a pull request on GitHub (you may want to look at this).
Skip it.