Git⚓︎
Config⚓︎
Cater for different users using git as user root⚓︎
In root's /.kshrc
SUDO_USER="${SUDO_USER:-'none'}"
if [ ${SUDO_USER} = "johndoe" ]; then
export GIT_AUTHOR_NAME="John Doe"
export GIT_COMMITTER_NAME="John Doe"
export GIT_AUTHOR_EMAIL="[email protected]"
export GIT_COMMITTER_EMAIL="[email protected]"
elif [ ${SUDO_USER} = "janedoe" ]; then
export GIT_AUTHOR_NAME="Jane Doe"
export GIT_COMMITTER_NAME="Jane Doe"
export GIT_AUTHOR_EMAIL="[email protected]"
export GIT_COMMITTER_EMAIL="[email protected]"
fi
Remotes⚓︎
Changing a remote's URL (https or ssh)⚓︎
$ git remote -v
origin https://github.com/Kristijan/notes.git (fetch)
origin https://github.com/Kristijan/notes.git (push)
$ git remote set-url origin https://github.com/somethingelse/notes.git
$ git remote -v
origin https://github.com/somethingelse/notes.git (fetch)
origin https://github.com/somethingelse/notes.git (push)
Add remote upstream after fork⚓︎
$ git remote -v
origin ssh://[email protected]:7999/~kristijan/repo.git (fetch)
origin ssh://[email protected]:7999/~kristijan/repo.git (push)
$ git remote add upstream ssh://[email protected]:7999/unix/repo.git
$ git remote -v
origin ssh://[email protected]:7999/~kristijan/repo.git (fetch)
origin ssh://[email protected]:7999/~kristijan/repo.git (push)
upstream ssh://[email protected]:7999/unix/repo.git (fetch)
upstream ssh://[email protected]:7999/unix/repo.git (push)
Pull down changes from both upstream and origin⚓︎
Aliases⚓︎
Decorated oneline graph⚓︎
One line summary⚓︎
git config --global alias.lgo "log --color --pretty=format:'%C(yellow)%h%Creset - %C(cyan)%ad%Creset %<(80,trunc)%s %C(cyan)%>(20,trunc)%an - %Cgreen%>(12)%ar%Creset' --date=short --abbrev-commit --all"
Commits⚓︎
Automatically commit all files being tracked⚓︎
Squashing commits and rebase onto master⚓︎
$ git switch master
$ git pull
$ git switch <other_branch>
$ git rebase -i master
pick dedd08d commit1
squash 8e782a4 commit2
squash 036bca2 commit3
squash ff8a125 commit4
$ git push --force-with-lease
Find parent commits of a merge⚓︎
$ git log --format=raw -n1
commit 61713c9ac641091c20045e9d3bde34f31d8e3621
tree 9d8c97f166cc9082c1949f21ed7b61a4fc33a420
parent c507b242517ba651b4fae5254c607571f666ffe2
parent a12033cb2e0933849a374defd272bd71a06b62ed
The highlighted commit above should be where the branch was before the merge.
Create empty commit⚓︎
Create an empty commit to do things like trigger builds, etc...
Show commit hash for each file⚓︎
$ git ls-files --sparse --full-name -z | xargs -0 -I FILE -P 20 git log -1 --date=iso-strict-local --format='%ad %>(14) %cr %<(5) %an %h ./FILE' -- FILE | sort --general-numeric-sort
2021-06-05T14:40:30+10:00 2 years, 5 months ago Kristian Milos d280e68 ./docs/gpfs.md
2021-06-05T14:40:30+10:00 2 years, 5 months ago Kristian Milos d280e68 ./docs/index.md
2021-06-05T14:40:30+10:00 2 years, 5 months ago Kristian Milos d280e68 ./docs/nim.md
2021-06-05T14:40:30+10:00 2 years, 5 months ago Kristian Milos d280e68 ./docs/vios.md
2021-06-05T14:40:30+10:00 2 years, 5 months ago Kristian Milos d280e68 ./docs/wpar.md
2021-06-05T14:59:15+10:00 2 years, 5 months ago Kristian Milos 170190d ./.github/workflows/ci.yml
...
Show all commit hashes for file⚓︎
$ git ls-files --sparse --full-name -z | xargs -0 -I FILE -P 20 git log --date=iso-strict-local --format='%ad %>(14) %cr %<(5) %an %h ./FILE' -- FILE | sort --general-numeric-sort
2023-01-11T17:19:25+11:00 10 months ago Kristian Milos cac3a2a ./docs/git.md
2023-03-17T16:09:35+11:00 7 months ago Kristian Milos 9633d50 ./docs/aix.md
2023-03-23T12:41:12+11:00 7 months ago Kristian Milos 0c1ce12 ./docs/aix.md
2023-06-09T12:00:20+10:00 5 months ago Kristian Milos 30b8b9b ./docs/git.md
2023-06-15T17:06:15+10:00 4 months ago Kristian Milos 229804b ./docs/aix.md
2023-06-15T17:14:56+10:00 4 months ago Kristian Milos 358c456 ./docs/aix.md
...
Show commit count for each file⚓︎
This will list which files have been in commits the most.
$ git log --pretty=format: --name-only | sed '/^$/d' | sort | uniq -c | sort -g
1 docs/CNAME
1 docs/gpfs.md
1 docs/nim.md
1 docs/vios.md
1 docs/wpar.md
2 .gitignore
4 docs/hmc.md
4 docs/index.md
4 docs/powerha.md
7 .github/workflows/ci.yml
10 docs/aix.md
11 mkdocs.yml
15 docs/git.md
Branches⚓︎
Create new branch and switch⚓︎
Create new branch from another branch and switch⚓︎
Switch back and forth between two different branches⚓︎
Update a branch with changes from master⚓︎
Reset local branch to match remote⚓︎
Rename a branch⚓︎
Rename branch if already pushed to remote⚓︎
Delete a branch⚓︎
Delete a remote branch⚓︎
List all branches and the commit they point to⚓︎
Delete local remote tracking branch if the remote branch has been merged⚓︎
git checkout master
git remote update origin --prune
git branch --merged | grep -v master | xargs git branch -d
Logs⚓︎
Condensed summary⚓︎
Decorated graph⚓︎
Details of a specific commit⚓︎
List of commits per user⚓︎
git shortlog -sne
16 Kristian Milos <[email protected]>
2 Goat Man <[email protected]>
2 Mwark <[email protected]>
List of commits per user after a certain date⚓︎
git shortlog -sne --after 2023-06-01
16 Kristian Milos <[email protected]>
2 Goat Man <[email protected]>
Blame⚓︎
Show blame from a specific line in a file⚓︎
This will show a git blame of 10 lines commencing at line 14.
Diff⚓︎
Diff from staged files⚓︎
Show committed files to be pushed to remote⚓︎
Diff between local and remote file⚓︎
Diff between two branches⚓︎
Diff between file in two different branches⚓︎
Diff of filenames between two commits/branches⚓︎
git diff --name-only <commit1/branch1> <commit2/branch2>
git diff --name-status <commit1/branch1> <commit2/branch2>
git diff --stat <commit1/branch1> <commit2/branch2>
Diff contents of a single file between two commits⚓︎
Difference between .. and ... in a git diff⚓︎
foo..bar or foo bar⚓︎
git diff foo..bar is the same as git diff foo bar, both will show you the difference between the tips of the two branches foo and bar.
%%{init: { 'theme': 'dark', 'gitGraph': {'mainBranchOrder': 1, 'parallelCommits': true}} }%%
gitGraph:
commit id: 'a'
commit id: 'b'
commit id: 'c'
branch feature1 order: 0
branch feature2 order: 2
switch feature1
commit id: 'd'
commit id: 'e'
commit id: 'foo' type: HIGHLIGHT
switch feature2
commit id: 'g'
commit id: 'h'
commit id: 'bar' type: HIGHLIGHT
foo...bar or $(git merge-base foo bar) bar⚓︎
git diff foo...bar (or $(git merge-base foo bar) bar) will show you the difference between the "merge base" of the two branches and the tip of bar. The "merge base" is usually the last commit in common between those two branches, so this command will show you the changes that your work on bar has introduced, while ignoring everything that has been done on foo in the meantime.
%%{init: { 'theme': 'dark', 'gitGraph': {'mainBranchOrder': 1, 'parallelCommits': true}} }%%
gitGraph:
commit id: 'a'
commit id: 'b'
commit id: 'merge base' type: HIGHLIGHT
branch feature1 order: 0
branch feature2 order: 2
switch feature1
commit id: 'd'
commit id: 'e'
commit id: 'foo'
switch feature2
commit id: 'g'
commit id: 'h'
commit id: 'bar' type: HIGHLIGHT
Tags⚓︎
Tag an existing commit⚓︎
Push all tags to remotte⚓︎
Push a single tag to remote⚓︎
Delete local tag⚓︎
Delete remote tag⚓︎
Update local tags from remote⚓︎
Show the commit a tag is pointing to⚓︎
Reset, Restore, & Remove⚓︎
Unstage a file⚓︎
Undo last commit that hasn't been pushed⚓︎
Discard all branch changes and refresh from remote⚓︎
Unstaging a file, but leaving its actual changes untouched⚓︎
Discard local changes in a certain file⚓︎
Undo all local changes in the working copy⚓︎
Restore any previous version of a specific file⚓︎
Remove a staged file⚓︎
git showing unstaged changes⚓︎
Miscellaneous⚓︎
Using git bisect to find bad commits⚓︎
-
Start the bisect and provide both the 'good' and 'bad' commit hashes.
$ git bisect start status: waiting for both good and bad commits $ git bisect good 72f09f status: waiting for bad commit, 1 good commit known $ git bisect bad fd1bbb5 Bisecting: 11 revisions left to test after this (roughly 4 steps) [adf2e0caec46fa82eea3ae4754fd0bea8d137e3d] fixed shellcheck SC2015 violation -
Run your tests, marking each failed test as 'bad'.
$ git bisect bad Bisecting: 2 revisions left to test after this (roughly 2 steps) [de1031a7d43aeb355482890159f53437094bf7a9] make sure to use /usr/bin/infocmp to probe if tmux-256color is available system wide (3), fixes #618 $ git bisect bad Bisecting: 0 revisions left to test after this (roughly 1 step) [044d6336e84034c14760a2fe178f604a89626bfb] make sure to use /usr/bin/infocmp to probe if tmux-256color is available system wide (2), fixes #617 -
When your test passes, mark the commit as 'good'
$ git bisect good 044d6336e84034c14760a2fe178f604a89626bfb is the first bad commit commit 044d6336e84034c14760a2fe178f604a89626bfb Author: Gregory Pakosz <[email protected]> Date: Sat Jan 21 21:57:51 2023 +0100 make sure to use /usr/bin/infocmp to probe if tmux-256color is available system wide (2), fixes #617 some operating systems like NixOS don't have /usr/bin/infocmp .tmux.conf | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)The highlighted commit above should be where the bug/issue was introduced.
-
Once complete, clean up the bisection state and return to the original HEAD.
List of files/blobs sorted by size⚓︎
$ git rev-list --objects --all |
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
sed -n 's/^blob //p' |
sort --numeric-sort --key=2 |
cut -c 1-12,41- |
$(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
...
...
...
83367b100bdf 50KiB docs/aix.md
e0f87ab30a21 50KiB docs/aix.md
815a3edec4d5 50KiB docs/aix.md
a11c5026a642 53KiB docs/aix.md
bd015cca4288 53KiB docs/aix.md
9c8f5774ab55 56KiB git/index.html
6c8a85661a40 58KiB powerha/index.html
11c2602bcedb 60KiB gpfs/index.html
3b7b4ecfc742 66KiB hmc/index.html
Search for a string in a file across all branches⚓︎
The below script takes two parameters. The first being the search string, and the second being the file to search. On a successful match, the script will print the name of the checked-out branch.
Disk space
The script will checkout every remote branch. In large repositories, this can consume a lot of disk space.
#!/bin/bash
# Search for a string in a file across all branches
if [ "$#" -ne 2 ]; then
printf "%s\n" "$0 <search string> <file name>"
exit 1
fi
printf "%s\n\n" "Listing branches containing \"${1}\" in file \"${2}\""
# Fetch all remote branches
git fetch --all
# Loop through each remote branch
git branch -r | awk -F'/' '!/HEAD/{sub(/^[^\/]*\//, ""); print}' | while read -r branch; do
# Switch to branch
git switch --quiet "${branch}"
# Check if the file contains the string
if git grep --quiet "${1}" -- "${2}"; then
echo "${branch}"
fi
# Checkout back to the original branch
git switch - --quiet
done
Commit a change to a file in every remote branch⚓︎
Disk space
The script will checkout every remote branch. In large repositories, this can consume a lot of disk space.
#!/bin/bash
# Commit a change to a file in every remote branch
# Fetch all remote branches
git fetch --all
# Loop through each remote branch
git branch -r | awk -F'/' '!/HEAD/ && !/production/ && !/main/{sub(/^[^\/]*\//, ""); print}' | while read -r branch; do
# Switch to branch
git switch --quiet "${branch}"
# Update Puppetfile
gsed -i '/mod '\''unix\/mwark'\''/,/mod /{//!d;};/mod '\''unix\/mwark'\''/d' Puppetfile
gsed -i '/mod '\''unix\/goats'\''/,/mod /{//!d;};/mod '\''unix\/goats'\''/d' Puppetfile
# Commit and push changes (if any)
if ! git diff --quiet; then
git add Puppetfile
git commit -m "Remove unix/mwark and unix/goats modules"
git push
fi
# Checkout back to the original branch
git switch - --quiet
done
Show ignored files⚓︎
$ git status --short --ignored
M spec/classes/init_spec.rb
M spec/classes/xormon_agent_spec.rb
M spec/spec_helper.rb
?? spec/fixtures/facts/aix-7.2-powerpc.facts
?? spec/fixtures/facts/aix-7.3-powerpc.facts
!! .ruby-lsp/.gitignore
!! .ruby-lsp/Gemfile
!! .ruby-lsp/Gemfile.lock
!! .ruby-lsp/main_lockfile_hash
!! .ruby-lsp/needs_update
!! .vscode/extensions.json
!! Gemfile.lock
!! bin/metadata-json-lint
!! bin/puppet
!! bin/puppet-lint
!! bin/rake
!! bin/rspec
!! bin/rubocop
!! spec/fixtures/manifests/site.pp
!! spec/fixtures/modules/cron_core/
!! spec/fixtures/modules/quadlets/
!! spec/fixtures/modules/stdlib/
!! spec/fixtures/modules/systemd/
!! spec/fixtures/modules/xormon
!! update_report.txt