Git  sandbox 

Distributed version control system

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