You created a sequence of commits,
feat-2, and you realize
feat-2 doesn't actually depend on
feat-1. I could make both of
these PRs against
main at the same time."
Given a repo like this:
git init touch A && git add A && git commit -m "A" touch B && git add B && git commit -m "B" git checkout -b "feat-1" touch C && git add C && git commit -m "C" git checkout -b "feat-2" touch D && git add D && git commit -m "D"
feat-1 to both be based off
main. You can't just
git checkout feat-2 git rebase main
Nothing happens, because a rebase replays commits onto the new base, and in
this case that would just replay the
feat-2 commits on
again (changing nothing).
Solution: only reply the
feat-2 commit on
--onto with a
cut-point! The form of the command is
git rebase --onto <Target> <Cut
git checkout feat-2 git rebase --onto main feat-1
Given a repo like this:
git init touch A && git add A && git commit -m "A" git checkout -b "feat-1" touch B && git add B && git commit -m "B" git checkout main touch C && git add C && git commit -m "C" touch D && git add D && git commit -m "D"
gitdot --png --msg
main would make
B point to
D. But say we wanted to
B on to
git checkout feat-1 git rebase --onto C
You locally committed to
main instead of
develop, but you haven't pushed
the commit yet.
- Soft-reset main back to origin/develop
- The committed changes will now be staged
- Switch to develop branch
- Commit staged changes
git reset --soft origin/develop
You rebased, and then remembered that the branch you were on has already been pushed to a remote repo. You shouldn't push this rebase!
- You need to return the current branch to where it was before the rebase.
You ran a
git commit --ammend, then realized you've already pushed the
commit you were ammending! You can't push the ammended commit! (You can,
but that would be rewriting history on the remote server).
- Reset soft to
origin/<branch-name>. Then the changes you just committed will be staged.
- Commit again as a new commit.
Somebody pushed changes to your branch while you were still committing locally. Now your branch and the remote branch have diverged.
- Option 1: Merge remote into local. Just do a git merge of remote/branch-name.
You make a change that ought to have been part of a previous commit, but that
previous commit is not the last commit (so you can't just
--amend the last
First, make this new commit and mark it as a
fixup of the offending commit:
git commit --fixup fb2f677
Next, run a
rebase --squash, which does a rebase where fixup commits are
squashed into the commits that they fix up. The commit hash is the commit where
the rebase is started from.
git rebase -i --squash ac5db87
HEAD is usually a symbolic ref, meaning it points to another ref. The exception is when you are in a detached HEAD state, in which case HEAD points directly to a commit.
git symbolic-ref HEAD
Some ways to print the SHA of the HEAD ref:
git rev-parse HEAD
git log -1 --format='%H'
Current branch name:
git rev-parse --abbrev-ref HEAD
Diff a branch with the commit you branched from.
git diff my-branch...main
Some ways to find the first commit in a Git repository:
git show $(git rev-list --max-parents=0 HEAD)
git log --reverse
Fun way to get the latest commit hash on a repo! (Or really, any commit hash for any ref). You don't even need the repo cloned locally.
git ls-remote \ https://github.com/cfclrk/rules_clojure.git \ refs/heads/master
git diff-tree -r --no-commit-id \ --name-only $sha
If HEAD is a tag, this will print the tag name. If not, it prints nothing.
git tag --points-at HEAD
git tag --list "v*"
git rev-parse --show-toplevel