In short:
One solution is to use grafts to connect history, then use git filter-branch
to rewrite history according to those grafts, then optionally do a merge.
Note that solution to replay your changes (your commits) on top of new development in original repository (the rebase solution) is another viable solution.
Longer version:
Let's assume that you either remember, or you can find by examining source and/or using git commands the revision of repository you downloaded snapshot of, and started local development. Let's call this revision START or A.
Let's assume that you local disconnected history is in the clone of original repository. It means that your local disconnected development is in the same repository as full history of a project. Let's assume that you local branches are in branch 'master' (and for simplicity that there is only one branch).
If you didn't fetched project into repository with your local disconnected work, you can do this with:
$ git add origin git://github.com/mojombo/mojombo.github.com.git
$ git fetch origin
The history looks now like the following:
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
x---y---*---*---* <--- master (your local disconnected history)
The commit named A in above diagram is the START commit you downloaded as snapshot and started your local development off.
There are two possibilities: you have comitted snapshot of 'A' as an initial commit 'x', or the first commit you made was with your local modifications.
In first case (you committed original starting state, e.g. as 'Initial commit' or 'Import') you would want the connected history to looks like this:
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
\
\-y---*---*---* <--- master (your local disconnected history)
i.e. your first original commit 'y' to have 'A' as a parent.
In the second case (you committed with your changes) you would want the connected history to look like this instead:
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
\
\-x---y---*---*---* <--- master (your local disconnected history)
i.e. you want first commit 'x' to have 'A" as a parent.
In both cases you want to find full SHA-1 identifier of commit 'A', and full SHA-1 identifiers of commits 'x' and 'y'.
You can find SHA-1 of commit 'A' (assuming that you don't know it already) with git rev-parse:
$ git rev-parse A # or A^{commit}
437b1b20df4b356c9342dac8d38849f24ef44f27
(the '^{commit}' suffix might be needed to make sure that you found commit SHA-1, which is important if you for example know 'A" by its tag, e.g. 'v0.99'; in your case it is not necessary, as the repository in question doesn't use tags).
You can find SHA-1 of commits 'x' and 'y' using git rev-list (assuming that you development was done on branch 'master'):
$ git rev-list --topo-order master | tail -2
8bc9a0c769ac1df7820f2dbf8f7b7d64835e3c68
e83c5163316f89bfbde7d9ab23ca2e25604af290
(the "| tail -2
" is here to find last two commits in generated list; you don't need to use it if you don't have it).
Note: in all examples above full SHA-1 are examples, and should not be used as is!
Let's name the commit that you want to have 'A" (or 'START') as a parent as FIRST (it would be 'x' or 'y', depending on you case, as stated above). Now we use grafts mechanism to connect history:
$ echo "<SHA-1 of FIRST> <SHA-1 of START>" > .git/info/grafts
Then you should check if you now have correctly connected (joined) history, by using graphical history browser such as gitk, or QGit, or GitX is you are on MacOS X, or even "git log --graph
", or "git show-branch
", e.g.:
$ gitk master origin/master # or --all
(where gitk is here only as an example; if you use "git show branch
" you not always can use '--all
' option).
Finally we would probably want to make those changes permanent, so anybody who would fetch from our repository would also have connected history. We can do this by using git filter-branch:
$ git filter-branch master
You would have original (disconnected) history in 'refs/original/master'.
Now you can remove grafts file:
$ rm .git/info/grafts
Now you would be able to merge in new development for original repository:
$ git merge origin/master
Setting up per-branch configuration, so that it would be enough to do simply "git pull" when on branch 'master' to pull (merge) changes in origin(al) repository is left as exercise for the reader... :-)
Note: the rebase solution would result in the following history (assuming that we have case where first comit was simple import):
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
\
\-y'---*'---*'---*' <--- master (your local disconnected history)
(where y'
means that commit y
was modified: it should be about the same changeset, but it is different as a commit).