如何将过去预先添加到git存储库? [英] How to prepend the past to a git repository?

查看:70
本文介绍了如何将过去预先添加到git存储库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到了一些源代码,并决定使用git,因为我的同事使用 mkdir $ VERSION 等方法。尽管代码的过去似乎并不重要,但我仍然希望将其置于git控制之下,以便更好地理解开发过程。因此:

将这些过去的版本放入我现有的git repo中的便利方法是什么?目前没有远程回购,因此我不介意重写历史记录,但是考虑到远程存储库的解决方案当然是首选,除非它更复杂。基于历史目录或归档文件,不需要任何更多交互的脚本的奖励点。

导入旧快照时,您会在 Git的contrib / fast中找到一些工具-import目录有用。或者,如果您已经在目录中拥有每个旧快照,则可以执行如下操作:




$ b

 #假设v * glob将以正确的顺序排序
#(即零填充,固定宽度的数值字段)
#对于v1,v2,v10,v11, ...你可以尝试:
#v {1..23}(1到23)
#v?{,?}(v +一个字符,然后v +两个字符)$ b $
#$(ls -vv *)(GNU ls具有版本排序)
#或$ {$ b $ v $ {,?{,?}}(v + {一,二,三} ,直接列出它们:``为foo​​ bar baz quux;做''
(git init import)
for v in v *;如果mv import / .git$ d /,则执行
;然后
(cd$ d&&git add --all&& git commit -mpre-Git snapshot $ d)
mv$ d / .gitimport /
fi
完成
(cd导入& git checkout HEAD - 。)

然后将旧的历史记录存入您的工作存储库:
$ b

  cd工作&& git fetch ../import master:old-history 






一旦将旧的历史记录和基于Git的历史记录同时存储在同一个存储库中,您可以选择一些前置操作选项:移植和替换。



移植是一个per-repository机制(可能暂时)编辑各种现有提交的血统。嫁接由 $ GIT_DIR / info / grafts 文件控制(在 gitrepository-layout manpage )。 b
$ b

  INITIAL_SHA1 = $(git rev-list --reverse master | head -1)
TIP_OF_OLD_HISTORY_SHA1 = $(git rev-parse old-history)
echo $ INITIAL_SHA1 $ TIP_OF_OLD_HISTORY_SHA1>> .git / info / grafts

移植到位(原始初始提交没有任何父母,移植给了它一个父母),你可以使用所有正常的Git工具来搜索并查看扩展历史记录(例如 git log 现在应该显示之后的旧历史记录您的提交)。



移植的主要问题是它们仅限于您的存储库。但是,如果你决定它们应该成为历史的永久部分,你可以使用 filter-branch 来制作它们(为你的做一个tar / zip备份。 git dir优先; git filter-branch 会保存原始文件,但有时使用普通备份会更容易。)

  git filter-branch --tag-name-filter cat  -  --all 
rm .git / info / grafts






替换机制更新(Git 1.6.5 +),但可以禁用它们( git --no-replace-objects ... ),并且它们可以被推送以实现更简单的共享。替换适用于单个对象(blob,树,提交或注释标签),因此该机制也更一般。替换机制记录在 git replace manpage 。由于一般性,prepending设置有一点涉及(我们必须创建一个新的提交,而不是仅仅命名新的父代):

 #旧历史分支的最后一次提交
oldhead = $(git rev-parse --verify old-history)
#当前提交的当前分支
newinit = $(git rev-list master | tail -n 1)
#创建一个基于$ newinit的伪提交,但是有一个父
#(注意:在这一点上, $ oldhead必须是完整的提交ID)
newfake = $(git cat-file commit$ newinit\
| sed/ ^ tree [0-9a-f] \ + \ $ / aparent $ oldhead\
| git hash-object -t commit -w --stdin)
#用假的替换最初的提交
git replace -f$ newinit $ newfake

分享这个替代品不是自动的。您必须推送部分(或全部) refs / replace 以分享替换品。

  git push some-remote'refs / replace / *'

如果您决定使替换为永久性,请使用 git filter-branch (与移植相同;对 .git 进行tar / zip备份首先是c $ c>目录):

  git filter-branch --tag-name-filter cat  -  --all 
git replace -d $ INITIAL_SHA1


I received some source code and decided to use git for it since my co-worker used the mkdir $VERSION etc. approach. While the past of the code currently seems unimportant, I'd still like to put it under git control as well to better understand the development process. So:

What is a convenient way to put those past versions into my already existing git repo? There is currently no remote repo so I don't mind rewriting history, but a solution that takes remote repositories into account will of course be preferred unless it is much more coplicated then. Bonus points for a script which does not need any more interaction based on either a directory or a archive file based history.

解决方案

For importing the old snapshots, you find some of the tools in Git's contrib/fast-import directory useful. Or, if you already have each old snapshot in a directory, you might do something like this:

# Assumes the v* glob will sort in the right order
# (i.e. zero padded, fixed width numeric fields)
# For v1, v2, v10, v11, ... you might try:
#     v{1..23}     (1 through 23)
#     v?{,?}       (v+one character, then v+two characters)
#     v?{,?{,?}}   (v+{one,two,three} characters)
#     $(ls -v v*)  (GNU ls has "version sorting")
# Or, just list them directly: ``for d in foo bar baz quux; do''
(git init import)
for d in v*; do
    if mv import/.git "$d/"; then
        (cd "$d" && git add --all && git commit -m"pre-Git snapshot $d")
        mv "$d/.git" import/
    fi
done
(cd import && git checkout HEAD -- .)

Then fetch the old history into your working repository:

cd work && git fetch ../import master:old-history


Once you have both the old history and your Git-based history in the same repository, you have a couple of options for the prepend operation: grafts and replacements.

Grafts are a per-repository mechanism to (possibly temporarily) edit the parentage of various existing commits. Grafts are controlled by the $GIT_DIR/info/grafts file (described under "info/grafts" of the gitrepository-layout manpage).

INITIAL_SHA1=$(git rev-list --reverse master | head -1)
TIP_OF_OLD_HISTORY_SHA1=$(git rev-parse old-history)
echo $INITIAL_SHA1 $TIP_OF_OLD_HISTORY_SHA1 >> .git/info/grafts

With the graft in place (the original initial commit did not have any parents, the graft gave it one parent), you can use all the normal Git tools to search through and view the extended history (e.g. git log should now show you the old history after your commits).

The main problem with grafts is that they are limited to your repository. But, if you decide that they should be a permanent part of the history, you can use git filter-branch to make them so (make a tar/zip backup of your .git dir first; git filter-branch will save original refs, but sometime it is just easier to use a plain backup).

git filter-branch --tag-name-filter cat -- --all
rm .git/info/grafts


The replacement mechanism is newer (Git 1.6.5+), but they can be disabled on a per-command basis (git --no-replace-objects …) and they can pushed for easier sharing. Replacement works on individual objects (blobs, trees, commits, or annotated tags), so the mechanism is also more general. The replace mechanism is documented in the git replace manpage. Due to the generality, the "prepending" setup is a little more involved (we have to create a new commit instead of just naming the new parent):

# the last commit of old history branch
oldhead=$(git rev-parse --verify old-history)
# the initial commit of current branch
newinit=$(git rev-list master | tail -n 1)
# create a fake commit based on $newinit, but with a parent
# (note: at this point, $oldhead must be a full commit ID)
newfake=$(git cat-file commit "$newinit" \
        | sed "/^tree [0-9a-f]\+\$/aparent $oldhead" \
        | git hash-object -t commit -w --stdin)
# replace the initial commit with the fake one
git replace -f "$newinit" "$newfake"

Sharing this replacement is not automatic. You have to push part of (or all of) refs/replace to share the replacement.

git push some-remote 'refs/replace/*'

If you decide to make the replacement permanent, use git filter-branch (same as with grafts; make a tar/zip backup of your .git directory first):

git filter-branch --tag-name-filter cat -- --all
git replace -d $INITIAL_SHA1

这篇关于如何将过去预先添加到git存储库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆