Created
November 24, 2009 21:39
-
-
Save kergoth/242252 to your computer and use it in GitHub Desktop.
"origin" scripts for tracking git cherry picks.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
These scripts are intended to make it easier to keep track of cherry picks | |
between long lived branches/forks. | |
The available scripts: | |
git-origin - associates an origin for a commit.. where it was cherry picked from | |
git-origin-blacklist - blacklists a commit from the output of the tools, | |
useful for bits you know are local-only | |
git-origins-from-patchid - uses patchids (like git-cherry) to generate an | |
initial set of origin data | |
git-cherry-origins - command like git-cherry, but which obeys the stored | |
origin information rather than patch-ids. this command | |
also, unlike git-cherry, supports some rev-list arguments | |
to limit the output by path (i.e. -- foo/bar). | |
git-log-origins - wrapper around git-cherry-origins which gives git-log-like | |
output. It will automatically use 'tig' as the pager if | |
available, otherwise falls back to less, then more. Takes | |
the same arguments as cherry-origins, as it just passes them | |
to it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -u | |
. $(dirname $0)/git-origins-setup | |
if [ $# -gt 0 ]; then | |
upstream="$1" | |
shift | |
else | |
upstream="$(git for-each-ref --format="%(upstream)" $(git rev-parse --symbolic-full-name HEAD))" | |
if [ -z "$upstream" ]; then | |
echo >&2 "No remote tracking branch for this branch, please supply upstream." | |
exit 1 | |
fi | |
fi | |
if [ $# -gt 0 ]; then | |
local="$1" | |
shift | |
else | |
local="HEAD" | |
fi | |
originfile="`mktemp`" || exit 1 | |
GIT_DIR="$(cd $(git rev-parse --git-dir) && pwd)" | |
blacklistfile="$GIT_DIR/origins-blacklist" | |
indexfile="$GIT_DIR/origins-index" | |
codir="$GIT_DIR/origins-co" | |
trap "rm -f $indexfile $originfile; exit" INT TERM EXIT | |
( | |
export GIT_INDEX_FILE="$indexfile" | |
export GIT_WORK_TREE="$codir" | |
mkdir -p $GIT_WORK_TREE && \ | |
git read-tree $GIT_NOTES_REF 2>/dev/null && \ | |
git checkout-index -af | |
) | |
git rev-list "$upstream" | while read hash; do | |
if [ -e "$codir/$hash" ]; then | |
cat "$codir/$hash" | |
fi | |
done >> $originfile | |
git rev-list --reverse "$upstream..$local" "$@" | while read hash; do | |
sym="+" | |
if grep -q "^$hash$" $originfile $blacklistfile 2>/dev/null; then | |
sym="-" | |
fi | |
if [ -e "$codir/$hash" ]; then | |
origins="$(cat $codir/$hash)" | |
for origin in $origins; do | |
if grep -q "^$origin$" $originfile 2>/dev/null || \ | |
[ "$(git merge-base $origin $upstream)" = "$origin" ]; then | |
sym="-" | |
break | |
fi | |
done | |
fi | |
echo "$sym $hash" | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
have () { | |
which "$1" >/dev/null 2>&1 | |
} | |
diffargs="-p --pretty --color" | |
if [ -z "$PAGER" ]; then | |
if [ -t 1 ] && have tig; then | |
PAGER=tig | |
diffargs="-v -s" | |
elif have less; then | |
PAGER="less -Xr" | |
elif have more; then | |
PAGER=more | |
else | |
PAGER=cat | |
fi | |
fi | |
git cherry-origins "$@" | \ | |
sed -n -e's/^+ //p' | \ | |
tac | \ | |
git diff-tree --stdin $diffargs | \ | |
eval $PAGER |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -ue | |
if [ $# -lt 1 ]; then | |
echo >&2 "Usage: $0 ORIGIN [CURRENT]" | |
exit 1 | |
elif [ $# -eq 1 ]; then | |
current="HEAD" | |
else | |
current="$2" | |
fi | |
origin="$(git rev-parse --verify $1)" | |
current="$(git rev-parse --verify $current)" | |
GIT_NOTES_REF=refs/notes/origins | |
export GIT_NOTES_REF | |
_reorder_by_date () { | |
# Return the commits in date order, first by author date, then by commit | |
# date, oldest to newest | |
git rev-parse "$@" | \ | |
git diff-tree -s -v --pretty=format:"%ai %ci %H%n" --stdin --root | \ | |
sort | \ | |
cut -d" " -f7 | |
} | |
reordered="$(_reorder_by_date $current $origin)" | |
origin="$(echo $reordered | cut -d" " -f1)" | |
current="$(echo $reordered | cut -d" " -f2)" | |
originorigin="$(git notes show $origin 2>/dev/null)" || true | |
if [ -n "$originorigin" ]; then | |
origin="$originorigin" | |
fi | |
prevdata="`mktemp`" || exit 1 | |
trap "rm -f $prevdata" INT TERM EXIT | |
git notes show $current 2>/dev/null | sort -u >>$prevdata || true | |
for hash in $origin; do | |
if [ "$hash" != "$current" ] && \ | |
! grep -q "^$hash$" $prevdata 2>/dev/null; then | |
echo $hash >> $prevdata | |
fi | |
done | |
if [ -z "$(cat $prevdata)" ]; then | |
echo >&2 "Empty prevdata, invalid commit/origin." | |
exit 1 | |
fi | |
git notes edit -F $prevdata $current | |
echo Set origin of $current to: | |
cat $prevdata |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
for hash in "$@"; do | |
echo "$hash" >> $(git rev-parse --git-dir)/origins-blacklist | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
. $(dirname $0)/git-origins-setup | |
if [ $# -gt 0 ]; then | |
upstream="$1" | |
shift | |
else | |
upstream="$(git for-each-ref --format="%(upstream)" $(git rev-parse --symbolic-full-name HEAD))" | |
if [ -z "$upstream" ]; then | |
echo >&2 "No remote tracking branch for this branch, please supply upstream." | |
exit 1 | |
fi | |
fi | |
if [ $# -gt 0 ]; then | |
local="$1" | |
shift | |
else | |
local="HEAD" | |
fi | |
patchidfile=`mktemp` || exit 1 | |
trap "rm -f $patchidfile; exit" INT TERM EXIT | |
_patchids "$upstream" >> $patchidfile | |
_patchids "$upstream..$local" | while read patchid commit; do | |
patchidline="$(grep "^$patchid " $patchidfile | head -n 1)" | |
if [ -n "$patchidline" ]; then | |
anorigin="$(echo $patchidline | cut -d" " -f2)" | |
git origin $anorigin $commit | |
fi | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GIT_NOTES_REF=refs/notes/origins | |
export GIT_NOTES_REF | |
_origins () { | |
git rev-list "$@" | while read hash; do | |
if git rev-parse -q --verify "$GIT_NOTES_REF":$hash >/dev/null; then | |
hashorigins="$(git show "$GIT_NOTES_REF":$hash)" | |
for origin in $hashorigins; do | |
echo $origin | |
done | |
fi | |
done | |
} | |
_patchids () { | |
git rev-list "$@" | git diff-tree -p --stdin | git patch-id | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment