git rebase - Reapply Git commits from copied fork repository to original repository -
a university colleague of mine thought idea fork repository cloning , copy contents new, freshly initialized repository without .git
folder original repository. afterwards, committed copy using single commit , whole team began working on project based on commit:
a <- b <- c <- d <- e (original repository) \ clone / |_____| \ / | \ / ofc. work on original repository continued after cloning... \ / m <- n <- o <-p (our "fork", commits team)
now, first goal following repository structure:
a <- b <- c <- n <- o <- p
what have been trying during past few hours following:
- clone original repository.
git diff > /path/to/patch
within fork.git apply
within original repository.- works, not preserve commits.
- various other things not work.
- clone original repository.
- create , switch new branch.
- reset commit
a
usinggit reset --hard commit_hash_a
. - create patch
n <- o <- p
usinggit format-patch commit_hash_m --stdout > /path/to/patch
on fork. - apply patch on original repository using
git -3 /path/to/patch
. after resolving several conflicts such duplicate creation of empty files, result in following error:fatal: sha1 information lacking or useless (some_file_name). repository lacks necessary blobs fall on 3-way merge.
cannot on.
so how create repository including commits original repository , our team described, eventually, pull request sent original repository? might git-rebase
help?
tl;dr;
in original repo clone, should:
git remote add colleague /path/to/colleague git fetch colleague git checkout -b colleague colleague/master git rebase master git checkout master git merge colleague
this give linear history , not leave behind redundant , parent-less m
commit.
this different david siro's answer, produce merge commit leaves redundant/parent-less m
commit floating around in branch merged from. don't dangling-commit scenario.
original post
i replicated , bad repository histories , able solve problem rebasing remote.
these steps followed:
- clone original repository
- add remote bad repo
- fetch bad repo
master
branch - branch fetched bad repo
- rebase bad master branch master (will claim changes applied)
- merge branch master
- push original repository
- schedule colleague's demise 😉
with setup, commands used , key output follows.
# # step 1 # $ git clone <path-to-original-repo> $ cd original-repo # # step 2 # $ git remote add messed-up-repo <path-to-messed-up-repo> # # step 3 # $ git fetch messed-up-repo # # step 4 # $ git checkout -b bad-master bad-orig/master # # step 5 # $ git rebase master first, rewinding head replay work on top of it... applying: commit m using index info reconstruct base tree... falling patching base , 3-way merge... no changes -- patch applied. applying: commit n applying: commit o applying: commit p # # step 5.1: @ new history # $ git log --oneline --graph --decorate * cc3121d (head -> bad-master) commit p * 1144414 commit o * 7b3851c commit n * b1dc670 (origin/master, origin/head, master) commit e * ec9eb4e commit d * 9c2988f commit c * 9d35ed6 commit b * ae9fc2f commit # # step 6 # $ git checkout master switched branch 'master' branch up-to-date 'origin/master'. $ git merge bad-master updating b1dc670..cc3121d fast-forward n.txt | 1 + o.txt | 1 + p.txt | 1 + 3 files changed, 3 insertions(+) create mode 100644 n.txt create mode 100644 o.txt create mode 100644 p.txt # # step 7 # $ git push counting objects: 9, done. delta compression using 8 threads. compressing objects: 100% (6/6), done. writing objects: 100% (9/9), 714 bytes | 0 bytes/s, done. total 9 (delta 3), reused 0 (delta 0) /tmp/repotest/good-orig.git b1dc670..cc3121d master -> master # # step 7.1: @ history again # $ git log --oneline --graph --decorate * cc3121d (head -> master, origin/master, origin/head, bad-master) commit p * 1144414 commit o * 7b3851c commit n * b1dc670 commit e * ec9eb4e commit d * 9c2988f commit c * 9d35ed6 commit b * ae9fc2f commit
you can destroy colleague's messed repository fire , others continue using original, , fixed, repository.
note: in post, said wanted commits:
a <- b <- c <- n <- o <- p
but solution includes commits d
, e
inbetween: a <- b <- c <- d <- e <- n <- o <- p
. if really want throw commits away, i.e. assuming it's not typo in post, can git rebase -i head~5
, remove pick
lines commits, , git push --force
repo's origin.
i'm assuming understand implications of re-writing history , need communicate users don't bit it.
for sake of completeness, replicated setup follows:
- create original repo history:
a <- b <- c
- manually copied original contents messed repo
- generate messed commit history:
m <- n <- o <- p
,m
has same content originala <- b <- c
- add work original repo:
... c <- d <- e
Comments
Post a Comment