Has no upstream branch errors in git [1] can be such a damn productivity killer.
You gotta stop your flow and swap over the branch, there is a config so that
you don’t have to do this.
fatal has no upstream branch # [2]
If you have not yet configured git to always push to the current branch, you
will get a has no upstream branch error if you don’t explicitly set it.
Let’s show an example
git checkout -b feat/ingest-inventory-data
git add conf/base/catalog.yml
git commit -m "feat: ingest inventory data from abc-db"
git push
You will be presented with the following error.
fatal: The current branch feat/ingest-inventory-data has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feat/ingest-inventory-data
Option 1: follow the instructions # [3]
To resolve this fatal error your first option is simply to follow the
instructions given. Just copy and paste it in.
git push --set-upstream origin feat/ingest-inventory-data
Option 2: push to the current branch without setting upstream # [4]
Honestly, I am pretty aware of the branch I am on, and Very few times have I
ever accidentally pushed to the wrong branch. The on...
Posts tagged: git
All posts with the tag "git"
25 posts
latest post 2026-05-06
Publishing rhythm
Once you give a branch the big D (git branch -D mybranch) its gone,
its lost from your history. It’s completely removed from your log.
There will be no reference to these commits, or will there?
TLDR # [1]
Checkout is your savior, all you need is the commit hash.
Immediate Regret # [2]
your terminal is still open
We have all done this, you give branch the big D only to realize it was
the wrong one. Don’t worry, not all is lost, this is the easiest to
recover from. When you run the delete command you will see something
like this.
❯ git branch -D new
Deleted branch new (was bc02a64).
Notice the hash is right there is the hash of your commit. You can use
that to get your content back.
git checkout -b bc02a64
git branch new
# or in one swoop checkout your new branch at the `start-point` you want
git checkout -b new bc02a64
Delayed reaction # [3]
you have closed your terminal
If you have closed your terminal, or have deleted with a gui or
something that does not tell you the hash as you run it, don’t fret, all
your work is still there (as long as you have commited). You just have
to dig it out. The reflog contains a list of all git [4] operations that
have occurred on your ...
It’s nearly impossible to completely loose a file if it is commited to git [1].
It’s likely harder to fully remove the file than it is to recover it, but how
do we go about recovering those precious files that we have lost.
Listing all the deleted files in all of git history can be done by
combining git log with --diff-filter. The log gives you lots of
options to show different bits of information about the commit that
happened at that point. It’s even possible to get a completely clean
list of files that are in your git history but have been deleted.
git log –diff-filter # [2]
These various commands will show all files that were ever deleted on
your current branch.
# This one includes the date, commit hash, and Author
git log --diff-filter D
# this one could be a git alias, but includes empty lines
git log --diff-filter D --pretty="format:" --name-only
# this one has the empty lines cleaned up
git log --diff-filter D --pretty="format:" --name-only | sed '/^$/d'
git diff-filter [3]
git reflog –diff-filter # [4]
The reflog can be super powerful in finding lost files here, as it only
cares about git operations, not just the current branch. It will search
accross all branch...
Git [1] commands such as diff, log, whatchanged all take a flag called
--diff-filter. This can filter for only certain types of diffs, such
as added (A), modified (M), or deleted (D).
Man page # [2]
You can find the full description by searching for --diff-filter in
the man git diff page.
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...)
changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used.
When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no
file that matches other criteria, nothing is selected.
Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths.
Note that not all diffs can feature all types. For instance, diffs from the index to the working tree can never have Added entries (because the set of paths
included in the diff is limited by what is in the index). Sim...
Git [1] has a built in way to rebase all the way back to the beginning of
time. There is no need to scroll through the log to find the first
hash, or find the total number of commits. Just use --root.
git rebase --root
References:
[1]: /glossary/git/
Git [1] reflog can perform some serious magic in reviving your hard work
from the dead if you happen to loose it.
caveat # [2]
You must git commit! If you never commit the file, git cannot help you.
You might look into your trashcan, filesystem versions, onedrive, box, dropbox.
If you have none of this, then you are probably hosed.
practice # [3]
I really like to practice these techniques before I need to use them so
that I understand how they work in a low stakes fashion. This helps me
understand what I can and cannot do, and how to do it in a place that
does not matter in any way at all.
This is what I did to revive a dropped docker-compose.yml file. The
idea is that if I can find the commit hash, I can cherry-pick it.
git init
touch readme.md
git add readme.md
git commit -m "add readme"
touch docker-compose.yml
git add docker-compose.yml
git commit -m "add docker-compose"
git reset 3cfc --hard
git reflog
# copy the hash of the commit with my docker-compose commit
git cherry-pick fd74df3
reflog # [4]
Here was the final reflog that shows all of my git actions. note I
did reset twice.
❯ git reflog --name-only
0404b6a (HEAD -> main) HEAD@{0}: cherry-pick: add docker-compo...
Right inside the git [1] docs [2],
is states that the git reflog command runs git reflog show by default which
is an alias for git log -g --abbrev-commit --pretty=oneline
This epiphany deepens my understanding of git, and lets me understand that most
git log flags might also work with git log -g.
full or short format # [3]
Here are some git commands for you to try out on your own that are all pretty
similar, but vary in how much information they show.
# These show only first line of the commit message subject, the hash, and index
git reflog
git log -g --abbrev-commit --pretty=oneline
# similar to git log, this is a fully featured log with author, date, and full
# commit message
git log -g
add files # [4]
If I am looking for a missing file, I might want to leverage --name-only or
--stat, to see where I might have hard reset that file, or deleted it.
git reflog --stat
git log -g --stat --abbrev-commit --pretty=oneline
git reflog --name-only
git log -g --name-only --abbrev-commit --pretty=oneline
example # [5]
Here is an example where I lost my docker-compose.yml file in a git reset,
and got it back by finding the commit hash with git reflog and cherry picked
it back.
❯...
I’ve never found a great use for a global .gitignore file. Mostly I fear
that by adding a lot of the common things like .pyc files it will be missing
from the project and inevitably be committed to the project by someone else.
Personal Tools # [1]
Within the past year I have added some tools to my personal setup that are not
required to run the project, but works really well with my setup. They are
direnv and pyflyby. Since these both support project level configuration,
are less common, and not in most .gitignore templates they make for great
candidates to add to a global .gitignore file.
create the config # [2]
Like any .gitignore it supports gits wildignore syntax. I made a
~/dotfiles/git/.global_gitignore file, and added the following to it.
.envrc
.pyflyby
.copier-defaults
.venv*/
.python-version
markout
.markata.cache
Once I had this file, I stowed it into ~/.global_gitignore.
cd ~/dotfiles/
stow git
Always stow your dotfiles, don’t set yourself up for wondering why your next
machine is not working right.
stow note # [3]
Note, the reason that it is a ~/.global_gitignore and not a ~/.gitignore is
that I was unable to stow a .gitignore file. They must be ignored by
...
Fugitive comes with a pretty sick way to commit files and see the diff at the
same time with verbose commit. Opening the fugitive menu with :G brings up
your git [1] status, you can stage files with s, unstage them with u, toggle
them with -, and toggle their diff with >. Once you have staged your files
for commit, you can commit with cc, but today I found that you can commit
verbose with cvc. This brings up not only a commit widow with your git
status shown, but the diff that you are about to commit.
[2]
example of a verbose commit in fugitive
References:
[1]: /glossary/git/
[2]: https://images.waylonwalker.com/fugitive-verbose-commit.png
Code Review from the comfort of vim | Diffurcate
I often review Pull requests from the browser as it just makes it so easy to see
the diffs and navigate through them, but there comes a time when the diffs get
really big and hard to follow. That’s when its time to bring in the comforts of
vim.
https://youtu.be/5NKaZFavM0E
Plugins needed # [1]
This all stems from the great plugin by
AndrewRadev [2]. It breaks a down
into a project. So rather than poping into a pager from git [3] diff,
you can pipe to diffurcate and it will setup a project in a tmp
directory for you and you can browse this project just like any
other except it’s just a diff.
Plug 'AndrewRadev/diffurcate.vim'
My aliases # [4]
First to quickly checkout PR’s from azure devops I have setup an alias to fuzzy
select a pr and let the az command do the checkout.
alias azcheckout='az repos pr checkout --id $(az repos pr list --output table | tail -n -2 | fzf | cut -d " " -f1)'
Next I have a few aliases setup for checking diffs. The first one checks what
is staged vs the...
Git in Depth Notes
These are my notes from taking @nnja’s FEM course git-in-depth [1].
requirements # [2]
- git --version > than 2.0
creating a git # [4]
echo "hello" | git hash-object --stdin
References:
[1]: https://frontendmasters.com/courses/git-in-depth/
[2]: #requirements
[3]: /glossary/git/
[4]: #creating-a-git
How I configure git
Git [1] can be a bit tricky to get configured correctly. I often stumble into
config issues weeks after setting up a new machine that I did not even notice.
These are my notes to remind me how I configure git.
Identity # [2]
git config --global user.name "John Doe"
git config --global user.email [email protected]
rebase # [3]
editor # [4]
git config --global core.editor nvim
default branch # [5]
git config --global init.defaultBranch main
push to current bransh wihtout setting upstream # [6]
git config --global push.default current
Autostash # [7]
git config pull.rebase true
git config rebase.autoStash true
References:
[1]: /glossary/git/
[2]: #identity
[3]: #rebase
[4]: #editor
[5]: #default-branch
[6]: #push-to-current-bransh-wihtout-setting-upstream
[7]: #autostash
How to use git cherry pick
~/git via 🐍 v3.8.5
❯ mkdir git-cherry-pick-learn
~/git via 🐍 v3.8.5
❯ cd git-cherry-pick-learn
~/git/git-cherry-pick-learn
❯ git init
Initialized empty Git repository in /home/walkews/git/git-cherry-pick-learn/.git/
git-cherry-pick-learn on main
❯ touch readme.md
git-cherry-pick-learn on main [?]
❯ git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
readme.md
nothing added to commit but untracked files present (use "git add" to track)
git-cherry-pick-learn on main [?]
❯ git add .
git-cherry-pick-learn on main [+]
❯ git commit -m "init readme"
[main (root-commit) ebd1ff2] init readme
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 readme.md
git-cherry-pick-learn on main
❯ echo "Learn Cherry Pick"
Learn Cherry Pick
git-cherry-pick-learn on main
❯ git add .
git-cherry-pick-learn on main
❯ git commit -m "add title
git-cherry-pick-learn on main
❯ echo "# Learn Cherry P...
Trim unused git branches
Trim branches no longer on origin # [1]
git remote prune origin --dry-run
git remote prune origin
Find branches already merged # [2]
git checkout main
# list remote branches that have already been merged into main
git branch -r --merged
# list local branches that have already been merged into main
git branch --merged
References:
[1]: #trim-branches-no-longer-on-origin
[2]: #find-branches-already-merged
Gitui is a blazing fast terminal git interface
Gitui is a terminal-based git user interface (TUI) that will change the way that you work with git.
Gitui is a blazing fast terminal git interface
Gitui is a terminal-based git [1] user interface (TUI) that will change the way
that you work with git. I have been a long-time user of the git cli, and it’s
been hard to beat, mostly because there is nothing that keeps my fingers on the
keyboard quite like it, except gitui which comes with some great ways to very
quickly walk through a git project.
installation # [2]
Go to their [releases]https://github.com/extrawurst/gitui/releases) page,
download the latest build, and pop it on your PATH. I have the following
stuffed away in some install scripts to get the latest version.
install latest release
GITUI_VERSION=$(curl --silent https://github.com/extrawurst/gitui/releases/latest | tr -d '"' | sed 's/^.*tag\///g' | sed 's/>.*$//g' | sed 's/^v//')
wget https://github.com/extrawurst/gitui/releases/download/v${GITUI_VERSION}/gitui-linux-musl.tar.gz -O- -q | sudo tar -zxf - -C /usr/bin/
run gitui # [3]
It opens blazing fast.
gitui
Quick Commits # [4]
Sometimes I edit a number of fi...
Fix git commit author
I was 20 commits into a hackoberfest PR when I suddenly realized they they all had my work email on them instead of my personal email 😱. This is the story of how I corrected my email address on 19 individual commits after already submitting for a PR.
- Change the email for this repo [1]
- Prepare for rebasing [2]
- start the rebase [3]
- 🛠 Fix First wrong Commit [4]
- Fix all commits [5]
- Done [6]
- ReCap [7]
Change the email for this repo # [1]
stop the bleeding
Before anything else set the email correctly!
cd kedro
git config user.name "Waylon Walker"
git config user.email [email protected]
Prepare for rebasing # [2]
First thing is to find how many commits back this mistake goes. I opened up the git [8] log, and saw mine went back 19 commits. I rolled back 20 just to be sure.
$ git log
...
commit a355926b9d7ec4c05659adaa254beefbdb036332
Author: WaylonWalker <[email protected]>
Date: Sat Oct 17 10:28:59 2020 -0500
give name of function inside incorrect parameters erro...
List the latest files to change in a git repo
while read file; do echo $(git log --pretty=format:%ad -n 1 --date=raw -- $file) $file; done < <(git ls-tree -r --name-only HEAD | grep static/stories) | sort -r | head -n 3 | cut -d " " -f 3
Strip Trailing Whitespace from Git projects
A common linting error thrown by various linters is for trailing whitespace. I
most often use flake8. I generally have
[pre-commit](https://waylonwalker.com/pre-commit-is-awesome
hooks setup to strip this,
but sometimes I run into situations where I jump into a project without it, and
my editor lights up with errors. A simple fix is to run this one-liner.
One-Liner to strip whitespace # [1]
bash
git grep -I --name-only -z -e '' | xargs -0 sed -i -e 's/[ \t]\+\(\r\?\)$/\1/'
[2]
read more about how pre-commit is awesome [3]
References:
[1]: #one-liner-to-strip-whitespace
[2]: https://waylonwalker.com/pre-commit-is-awesome
[3]: /pre-commit-is-awesome/