Skip to content

Git

Configuration

Setting up multiple Git profiles

When using git as the version control tool for both personal and work related projects, it might be interesting to isolate the two (or more) profiles.

In your home directory, create the following files:

$ ls -la
-rw-rw-rw-  1 root root  483 Aug 25 08:07 .gitconfig
-rw-rw-rw-  1 root root   57 Apr  2  2021 .gitconfig-personal
-rw-r--r--  1 root root   57 Aug  5  2021 .gitconfig-work

Add the following to .gitconfig:

[includeIf "gitdir:/path/to/personal/projects/directory"]
    path = .gitconfig-personal
[includeIf "gitdir:/path/to/work/projects/directory"]
    path = .gitconfig-work
[...]

Each subsequent configuration file can then define it's own user and Git settings, e.g.:

$ cat .gitconfig-personal
[user]
  name = John Doe
  email = [email protected]
[help]
  autocorrect = 1
$ cat .gitconfig-work
[user]
  name = John Doe
  email = [email protected]
[diff]
  tool = icdiff
[difftool]
  prompt = false
[icdiff]
  options = --highlight --line-numbers

Automatically sign commits

On Debian:

$ apt-get install gnupg2
$ gpg2 --import file.asc
$ gpg2 --list-secret-keys --keyid-format=long
/root/.gnupg/pubring.kbx
------------------------
sec   rsa4096/632C9BB6CF21205A 2015-09-30 [SC]
      6F2B0C373EBE0DD7975D51B9632C2AA6CF21205A
uid                 [ unknown] John Doe <[email protected]>
ssb   rsa4096/9C04F25B59B68D59 2015-09-30 [E]

$ eval "$(keychain --stop others --quiet --quick --eval --agents gpg,ssh\
    --inherit any --timeout 31622400 ~/.ssh/id_example1 ~/.ssh/id_example2\
    ~/.ssh/id_example3 632C9BB6CF21205A)"
$ echo "test" | gpg2 --clearsign

Add the following to .gitconfig:

[commit]
  gpgsign = true
[gpg]
  program = gpg2

and the following to .gitconfig-xxxxxxx

  signingkey = 632C9BB6CF21205A

Usage

Anonymous Git commits

From inside your local git repository:

$ git config user.name 'Anonymous'
$ git config user.email '<>'

Source: Stackoverflow

Squash last <n> commits

If you want to write the new commit message from scratch, this suffices:

$ git reset --soft HEAD~<n>
$ git commit
$ git push -f

If you want to start editing the new commit message with a concatenation of the existing commit messages (i.e. similar to what a\ pick/squash/squash/…/squash git rebase -i instruction list would start you with), then you need to extract those messages and pass them to git commit:

$ git reset --soft HEAD~<n>
$ git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
$ git push -f

Source: Stackoverflow

Squash all commits into one

Make sure everything is committed, and write down the latest commit_id in case something goes wrong, or create a separate branch as a backup.

Reset your head to the first commit, but leave your index unchanged. All changes since the first commit will now appear ready to be committed.

$ git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`

Amend your commit to the first commit and change the commit message.

$ git commit --amend -m "initial commit"

# if you want to keep the existing commit message
$ git commit --amend --no-edit

Force push your changes.

user@host:~$ git push -f

Source: Stackoverflow

Delete tags

For a local tag, use

$ git tag -d <tag_name>

For a remote tag (if you've already pushed the tag)

$ git push --delete origin <tag_name>

Syncing a fork

$ git fetch upstream
$ git checkout master
$ git merge upstream/master

Commit only part of a file's changes

Use git add -e myfile to open the file in a text editor and choose which lines you'd like to stage and which you want to ignore.

As you may known lines that start with + are addtions, lines that start with - are deletions. So:

To not stage an addition just delete that line.
To not stage a deletion just replace - with space