Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x-yuri/bc3c429689fd171cc49681318b5168a8 to your computer and use it in GitHub Desktop.
Save x-yuri/bc3c429689fd171cc49681318b5168a8 to your computer and use it in GitHub Desktop.
Copying commits between unrelated repositories w/o adding a remote

Copying commits between unrelated repositories w/o adding a remote

Based on Copying commits between unrelated repositories.

a.sh:

set -eux
rm -rf a b

show_state() {
    echo {{{
    git --no-pager log --oneline --graph --all
    set +x
    git_log `git rev-parse HEAD`
    # (cd .git/objects && fd -t f)
    for h in `cd .git/objects && fd -t f -E info -E pack | tr -d /.`; do
        echo -- $h
        git cat-file -p "$h"
    done
    set -x
    if [ -e .git/objects/pack/pack-*.idx ]; then
        git verify-pack -v .git/objects/pack/pack-*.idx
    fi
    echo }}}
}

git_log() {
    local commit=$1
    while [ "$commit" ]; do
        head=$(git cat-file -p `git rev-parse "$commit"` | head -2)
        tree=`echo "$head" | egrep '^tree ' | awk '{print $2}'`
        parent=`echo "$head" | egrep '^parent ' | awk '{print $2}'`
        echo "commit: $commit"
        echo "  tree: $tree"
        if [ "$parent" ]; then
            echo "  parent: $parent"
        fi
        git cat-file -p "$tree" | sed -r 's/^/  /'
        commit=$parent
    done
}

mkdir a
(cd a
git init
echo '1
2
3' > a
git add a
git commit -m 1,2,3
sed -Ei 's/3/33/' a
git add a
git commit -m '3 -> 33'
git format-patch -1 HEAD)

mkdir b
(cd b
git init
echo '11
2
3' > a
git add a
git commit -m 11,2,3

set +x
index=`egrep '^index ' ../a/0001-3-33.patch`
before=`echo "$index" | sed -r 's/index (\w+)\.\.(\w+).*/\1/'`
echo "before: $before"
after=`echo "$index" | sed -r 's/index (\w+)\.\.(\w+).*/\2/'`
echo "after: $after"
set -x

(cd ../a
git cat-file blob "$before") | git hash-object -w --stdin

# git remote add a ../a
# git fetch a

cat a
cat ../a/0001-3-33.patch
# show_state
git --no-pager log --oneline --graph --all
git am -3 "$@" ../a/0001-3-33.patch
# show_state
git --no-pager log --oneline --graph --all

# git remote rm a

git gc --prune=now
# show_state
)
$ sh a.sh
+ rm -rf a b
+ mkdir a
+ cd a
+ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
Initialized empty Git repository in /tmp/tmp.TDsaH0agCe/a/.git/
+ echo '1
2
3'
+ git add a
+ git commit -m 1,2,3
[master (root-commit) 0ad0231] 1,2,3
 1 file changed, 3 insertions(+)
 create mode 100644 a
+ sed -Ei s/3/33/ a
+ git add a
+ git commit -m '3 -> 33'
[master 02ab69b] 3 -> 33
 1 file changed, 1 insertion(+), 1 deletion(-)
+ git format-patch -1 HEAD
0001-3-33.patch
+ mkdir b
+ cd b
+ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
Initialized empty Git repository in /tmp/tmp.TDsaH0agCe/b/.git/
+ echo '11
2
3'
+ git add a
+ git commit -m 11,2,3
[master (root-commit) f90c888] 11,2,3
 1 file changed, 3 insertions(+)
 create mode 100644 a
+ set +x
before: 01e79c3
after: ce5ad9f
+ cd ../a
+ git cat-file blob 01e79c3
+ git hash-object -w --stdin
01e79c32a8c99c557f0757da7cb6d65b3414466d
+ cat a
11
2
3
+ cat ../a/0001-3-33.patch
From 02ab69b168dcb2adbf73e05ac4e36c02f23a85fb Mon Sep 17 00:00:00 2001
From: Yuri Kanivetsky <yuri.kanivetsky@gmail.com>
Date: Sat, 16 Jul 2022 19:29:16 +0300
Subject: [PATCH] 3 -> 33

---
 a | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/a b/a
index 01e79c3..ce5ad9f 100644
--- a/a
+++ b/a
@@ -1,3 +1,3 @@
 1
 2
-3
+33
-- 
2.36.1

+ git --no-pager log --oneline --graph --all
* f90c888 11,2,3
+ git am -3 ../a/0001-3-33.patch
Applying: 3 -> 33
Using index info to reconstruct a base tree...
M	a
Falling back to patching base and 3-way merge...
Auto-merging a
+ git --no-pager log --oneline --graph --all
* 1792554 3 -> 33
* f90c888 11,2,3
+ git gc --prune=now
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment