Git sandbox
What is git?
Distributed version control system.
git repo history git hooks git hooks redux
History
Linus developed git after being frustrated with the state of version control systems in that era. He had experienced the benefits of using a version control system using BitKeeper earlier, but given the restrictive terms, and removal of free tier, he decided to build something of his own.
Fun read, this one https://blog.brachiosoft.com/en/posts/git/
Aside, add “Just for Fun: The Story of an Accidental Revolutionary” to reading list
Internals
- How does git work?
- Why does it use filesystem instead of a database like other systems of the time?
- Is there a bottleneck?
- Can it be improved?
- What comes next?
Useful commands
Log
$ git log --oneline # show one line per commit
$ git log -5 --oneline # show last 5 commits
$ git log -5 --pretty="format:%C(white)%ai %C(yellow)%h %C(blue)%ae %C(reset)%s
$ git log --pretty="format:%C(white)%ai %C(yellow)%h %C(blue)%an %C(green)(%ae) %C(reset)%s" -6
2024-05-29 15:00:00 +0000 b06d833 Bot (bot@example.com) chore(release): 1.0.0 deployment
Amend
Change author name/email for commits already pushed to remote
$ git rebase -i HEAD~4
$ git commit --amend --no-edit --reset-author <commit hash>
Push
git push --force-with-lease
If somebody else built on top of your original history while you are rebasing, the tip of the branch at the remote may advance with their commit, and blindly pushing with –force will lose their work.
This option allows you to say that you expect the history you are updating is what you rebased and want to replace. If the remote ref still points at the commit you specified, you can be sure that no other people did anything to the ref. It is like taking a “lease” on the ref without explicitly locking it, and the remote ref is updated only if the “lease” is still valid.
Manage multiple Git “workspaces”
Work1, work2, personal etc. etc.
Separate the workspaces into different directories, like -
.
├── gitlab
├── github
└── workgithub
Next, in ~/.gitconfig
, create individual configs for each directory
# ~/.gitconfig
[user]
name = username
email = username@email.com
[includeIf "gitdir/i:~/code/gitlab/"]
path = ~/.gitlab.gitconfig
[includeIf "gitdir/i:~/code/github/"]
path = ~/.github.gitconfig
[includeIf "gitdir/i:~/code/workgithub/"]
path = ~/.workgithub.gitconfig
# no need to use --set-upstream origin branch
[push]
autoSetupRemote = true
Specify the relevant email, name in directory specific gitconfig
file.
# ~/.gitlab.gitconfig
[user]
name = gluser
email = gluser@gitlab.com
# ~/.github.gitconfig
[user]
email = ghuser@users.noreply.github.com
name = ghuser
# ~/.workgithub.gitconfig
[user]
email = ghworkuser@users.noreply.github.com
name = ghworkuser
Modify your ssh
config to use the correct keys for each (don’t reuse the same keys!)
# ~/.ssh/config
Host gitlab.com
User git
IdentityFile ~/.ssh/glid_rsa
Host ghuser.github.com
User git
Hostname github.com
IdentityFile ~/.ssh/ghuserid_rsa
Host github.com
User git
IdentityFile ~/.ssh/ghworkuserid_rsa
Finally, when adding an origin
for repos under github
directory, use the HOST value. Since it is overridden by HOSTNAME, there is no other impact.
# first
git remote add origin git@ghuser.github.com:ghuser/repo.git
# edit existing origin
git remote set-url origin git@ghuser.github.com:ghuser/repo.git
LFS
- Can you use webp images in git to reduce the binary file sizes?
- How do you convert png to webp images?
References
- Official site - https://git-scm.com
- Book - https://git-scm.com/book/en/v2