If you want to move the HEAD
to the parent of the current HEAD
, that's easy:
git reset --hard HEAD^
But is there any simple way to do the exact opposite of this operation, that is, set the head to the current head's first child commit?
Right now, I use gitk as a workaround (alt-tab, up-arrow, alt-tab, middle-click), but I would like a more elegant solution, one that can also be used when gitk is not available.
If you want to go to a particular commit of a git repository with submodules you can use 2 git commands: reset or checkout. You will also need to synchronise the submodules after the working directory has been altered as that doesn't happen automatically.
The parent commit is the commit this current commit is based on. Usually: When you git commit normally, the current commit becomes the parent commit of the new commit that's introduced by the command.
To jump back to a previous commit, first find the commit's hash using git log . This places you at commit 789abcd . You can now make new commits on top of this old commit without affecting the branch your head is on. Any changes can be made into a proper branch using either branch or checkout -b .
Create a new orphan branch, named <new_branch>, started from <start_point> and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and commits.
Very probably not the fastest possible solution, but it does what I need:
#!/bin/bash REV=$1 if [[ -z "$REV" ]]; then echo "Usage: git-get-child []" exit fi HASH=$(git rev-parse $REV) NUM=$2 if [[ -z "$NUM" ]]; then NUM=1 fi git rev-list --all --parents | grep " $HASH" | sed -n "${NUM}s/\([^ ]*\) .*$/\\1/p"
The git rev-list --all --parents
does exactly what I need: it iterates over all reachable commits, and prints the following line for each:
SHA1_commit SHA1_parent1 SHA1_parent2
etc.
The space in the grep expression ensures that only those lines are found where the SHA1 in question is a parent. Then we get the nth line for the nth child and get the child's SHA1.
The above method using git rev-list --all
considers all available commits, which can be a lot and is often not necessary. If the interesting child commits are reachable from some branch, the number of commits that a script interested in child commits needs to process can be reduced:
branches=$(git branch --contains $commit| grep -v '[*] ('| sed -e 's+^..++')
will determine the set of branches that $commit is an ancestor of. With a modern git, at least version 2.21+, this should do the same without the need for sed
(untested):
branches=$(git branch --format='%(refname:short)' --contains $commit| grep -v '[*] (')
Using this set, git rev-list --parents ^$commit $branches
should yield exactly the set of all parent-child relationships between $commit and all branch heads that it is an ancestor of.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With