Not so long ago after I learned the ropes of Git, what got me curious was magic trick developers would do
to manage changes and commit history.
On top of basics[1], what other Git commands/options[2] do you think you can level up with?
Not so long ago after I learned the ropes of Git, what got me curious was magic trick developers would do
to manage changes and commit history.
On top of basics[1], what other Git commands/options[2] do you think you can level up with?
On an update script for a game I like doing reset --hard and pull --rebase
I like the idea of resetting any local changes and pulling in any updates from the source as-is, but I never had any flags for that and git pulls just always worked. I found the hard and rebase flags on an unrelated troubleshooting post and they sounded cool ![]()
git commit --amend -m "update" .
Joking aside, I recently learned that I can delete a branch on a remote (e.g. github) from my local repo on my computer (so I don’t have to log in from a web browser):
git push -d remote_name remote_branch
The git stash command is useful to know.
You can stash changes to allow a git pull to work then unstash your changes,
I’d love that flexibility of keeping changes aside and staging them when needed.
Here are some which I find very useful.
# Interactively choose which files / part of files to add to the
# index. Pretty useful if you like to double check what code you
# are committing.
$ git add -p
$ git add -p src/
# Also works when stashing changes.
$ git stash -p
# Instead of using `-m` do not provide a message. Git will open
# the default text editor where you can type the commit message.
# The text editor will also show which files are going to be committed
# to which branch, so no need to run git status.
$ git commit
# When wanting to commit all changes in a directory, just use commit
# instead of doing a add + commit.
$ git commit src/
# Apply changes of an existing commit to the current branch.
$ git cherry-pick "$COMMIT"
# Revert the changes of a commit.
$ git revert "$COMMIT"
# Interactively manipulate the history of the last 10 commits. Drop,
# merge, edit or reorder commits.
$ git rebase -i HEAD~10
# Show the git history including the changes made by commits.
$ git log -p
I have a GUI tool that I wrote and use to interact with source code systems.
It supports git, subversion (svn) and partitially murcurial (hg).
It uses that stash command to make git pull reliable as one if its value adds.
You can see its home page here https://scm-workbench.barrys-emacs.org/
and I maintain it in copr here: barryascott/tools Copr
As I develop on Fedora, Windows and macOS my tools also run on all of them.
I maintain binary install kits for macOS and Windows.
Another thing that is useful to configure is commit signatures. If you are already using ssh keys for authentication to the git remote its pretty simple to reuse them for signing commits. Just add the following lines to your git config (~/.gitconfig or ~/.config/git/config):
[user]
email = ...
name = ...
signingKey = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOsxcpis76VmY0xfhwN7ZEC/Ud16Nes+eoWHZtHpEDg # <- place your public key here (`$ cat .ssh/id_ed25519.pub`)
[gpg]
format = ssh
[commit]
gpgSign = true
Its also possible to use gpg keys for signing, if you prefer gpg or are using bitbucket (which doesn’t support ssh key signatures) see the git documentation. After adding the git configuration go to github / gitea / gitlab and add your ssh key as signing key. Now your commits will have the verified badge next to them.
Without signatures its impossible for people to say for sure that you are the person that created the commit. Its very simple to create a commit with the credentials of another person:
$ git commit --author="John Doe <john@doe.com>"
I guess the other command I use a lot (via scm workbench) is git rebase.
That is how I reword commit messages, squish commits together and drop commits before git pushing them.
That git config is really handy working with projects in various places in Fedora Project and other upstream repos. Thanks a million.
There is a Git (and other VCS) integration plugin in KDE Dolphin, which is disabled by default. Enable it, and then Dolphin will show the state of files and folders in the local Git repository. The right-click menu also allows some basic Git operations.
Good to know. I use Kate. The Dolphin (and Konsole) is built-in.
There’s also a shortcut for that: git pull --rebase --autostash
I have a few git log variants that come in handy, taken from different places:
[alias]
lg = !"git lg1"
lg1 = !"git lg1-specific --all"
lgs1 = !"git lg1-specific --all --simplify-by-decoration"
lg2 = !"git lg2-specific --all"
lgs2 = !"git lg2-specific --all --simplify-by-decoration"
lg3 = !"git lg3-specific --all"
lgs3 = !"git lg3-specific --all --simplify-by-decoration"
lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
lg2-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
lg3-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(auto)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'
The git-worktree command is very very useful when one is working on different branches simultaneously. For example, if I’m writing a new quick doc and also reviewing one, I can have two worktrees and not have to keep switching between the two branches in one checkout of the folder:
https://git-scm.com/docs/git-worktree
For vim users, fugitive is really good:
There’s pre-commit that is very useful to run hooks before committing.
For Python code, for example, we use pre-commit to format our code before it can be committed:
(An idea could be to add a pre-commit hook for docs repos that can run the formatter and other tweaks before commits)
I use it along with git remote prune <remote>, which removes local copies of branches that don’t exist on the remote to clean up the local checkout a little.
Since we’re on Fedora’s discourse: Have something like
[includeIf "gitdir:~/fedora/"]
path = ~/.config/git/config.fedora
in your global git config (e.g. in ~/.config/git/config), and put all the things which you want for your Fedora work in ~/.config/git/config.fedora (assuming you work in repo clones below ~/fedora/), for example:
[alias]
fedtag = ! git tag $(fedpkg verrel)
[user]
email = mjg@fedoraproject.org
[push]
default = simple
If you feel fancy, you can make your life easier with dist-git: fetch via https (faster) and push via ssh; add your fork remotes with a URL like dist-git:mjg/rpms/forkedproject:
# ssh for pushes only
[url "https://src.fedoraproject.org/"]
insteadOf = dist-git:
[url "ssh://mjg@pkgs.fedoraproject.org/"]
pushinsteadOf = dist-git:
# rewrite "fedpkg clone" generated config
[url "https://src.fedoraproject.org/"]
insteadOf = ssh://mjg@pkgs.fedoraproject.org/
[url "ssh://mjg@pkgs.fedoraproject.org/"]
pushinsteadOf = ssh://mjg@pkgs.fedoraproject.org/
# convenience for my forks
[url "https://src.fedoraproject.org/forks/mjg/"]
insteadOf = dist-git:mjg/
[url "ssh://mjg@pkgs.fedoraproject.org/forks/mjg/"]
pushinsteadOf = dist-git:mjg/
Since I did not include rpms in the substitution you can use it for requests, flatpaks etc. also.
git log --oneline --decorate --graph --boundary <branch1>...<branch2>
is also useful to compare branches (local or remote)
I do use that a lot, but I haven’t got it down as an alias in gitconfig. Perhaps it’s time to add a lgdiff alias ![]()
This is excellent @job79, I had most of those in my ~/.gitconfig, but was missing the [commit] stanza.
Also, the value for signingKey can be the (full path to the) filename containing your SSH private key.
Here’s another ~/.gitconfig trick I learned a few years ago. This uses the Fedora package diff-so-fancy to perform granular highlighting of git diff. Change colors to suit your taste:
[color "diff-highlight"]
oldNormal = red bold
oldHighlight = red bold 52
newNormal = green bold
newHighlight = green bold 22
[color "diff"]
meta = yellow
frag = magenta bold
commit = yellow bold
old = red bold
new = green bold
whitespace = red reverse
[diff-so-fancy]
changeHunkIndicators = false
stripLeadingSymbols = false