简体   繁体   English

将本地 git 存储库的准确 state 复制到另一个本地存储库

[英]Copy exact state of local git repo to another local repo

Is there a way to copy the exact state of a local git repo (uncommitted changes and all) to another local repo?有没有办法将本地 git 存储库(未提交的更改和所有)的确切 state 复制到另一个本地存储库?

The destination repo should be switched to the exact state of the source repo, including the branch, commit and any uncommitted changes since the last commit - edits, new files, deletions...目标 repo 应该切换到源 repo 的确切 state,包括分支、提交和自上次提交以来任何未提交的更改 - 编辑、新文件、删除......

Short of copying the entire directory every time I need this functionality, I can't think how to do it.每次我需要这个功能时都没有复制整个目录,我想不出该怎么做。

Obviously checking the destination repo out to the same commit will be easy, however it's the uncommitted changes I'm not sure about.显然,将目标仓库检查到同一个提交会很容易,但是我不确定这是未提交的更改。

Edit (why I want this.) I am building a local build system (for Unity games), Normally whilst a build is underway inside of Unity you can't use the program for anything else.编辑(为什么我想要这个。)我正在构建一个本地构建系统(用于 Unity 游戏),通常在 Unity 内部进行构建时,您不能将该程序用于其他任何事情。 so I have a system where another instance of Unity makes the build on a carbon copy of the project files, Each time I trigger a build I delete the old copy and make a new copy.所以我有一个系统,其中另一个 Unity 实例在项目文件的副本上进行构建,每次触发构建时,我都会删除旧副本并制作新副本。 however my thinking is that if the copy is on the same commit and say only two uncommitted files different it would be much quicker just to patch the state.但是我的想法是,如果副本在同一个提交上并且说只有两个未提交的文件不同,那么仅修补状态会快得多。 I make builds of uncommitted work whilst testing so commiting changes isn't really an option!我在测试时构建未提交的工作,因此提交更改并不是一个真正的选择!

Any suggestions greatly appreciated!任何建议都非常感谢!

Cheers干杯

Short of copying the entire directory every time I need this functionality, I can't think how to do it.每次我需要这个功能时都没有复制整个目录,我想不出该怎么做。

What's wrong with copying the entire directory?复制整个目录有什么问题? If you really prefer not to (eg because it is huge), use any folder synchronization utility, such as rsync .如果您真的不想这样做(例如因为它很大),请使用任何文件夹同步实用程序,例如rsync I use both those approaches very often.我经常使用这两种方法。

You can use an archiver ( tar or whatever) to collect the entire repository-and-work-tree state and copying that to some other file-tree area:您可以使用存档器( tar或其他)收集整个存储库和工作树 state 并将其复制到其他文件树区域:

cd /path/to
tar cf - repo | (cd /different/path; tar xf -)

for instance copies the entire file-tree from /path/to/repo to /different/path/repo .例如,将整个文件树从/path/to/repo复制到/different/path/repo This copies both the repository itself—all the files in .git —and the work-tree (all the files that aren't in .git ).这会复制存储库本身( .git中的所有文件)和工作树(所有不在.git中的文件)。

There are a few caveats here.这里有一些警告。 The most important is that the .git underneath the top level of the work-tree must really be a directory containing the repository, not just a file like those created by git worktree add .最重要的是,工作树顶层下的.git必须确实是包含存储库的目录,而不仅仅是像git worktree add创建的文件。

Using in-Git methods, such as git clone , won't work: they only copy the repository .使用 in-Git 方法,例如git clone是行不通的:它们只复制存储库 The work-tree is not part of the repository:工作树不是存储库的一部分:

Short of copying the entire directory every time I need this functionality, I can't think how to do it.每次我需要这个功能时都没有复制整个目录,我想不出该怎么做。

That's because Git literally won't do it.那是因为 Git 字面上会这样做。 The work-tree— your work-tree—is yours , not Git's, and it's not part of the Git repository.工作树——你的工作树——是的,不是 Git 的,它不是 Git 存储库的一部分。 It's just there next to the repository, which is the stuff in the .git subdirectory.它就在存储库旁边,即.git子目录中的内容。

If you have Git 2.5 or later—preferably 2.15 or later, because there was a pretty nasty bug in it until then 1 —whatever you are thinking of doing like this is probably better handled through git worktree add .如果你有 Git 2.5 或更高版本——最好是 2.15 或更高版本,因为在此之前有一个非常讨厌的错误1——无论你想做什么,通过git worktree add可能会更好地处理。 That creates a separate work-tree, which again is yours and not Git's, in which Git does a git checkout of some commit or branch of your choice at the time you run git worktree add .这会创建一个单独的工作树,这又是您的,而不是 Git 的,其中 Git 在运行git worktree add时对您选择的某些提交或分支进行 git git checkout That second work-tree doesn't have its own repository: it uses the original work-tree's repository, by creating a file named .git instead of a directory named .git .第二个工作树没有自己的存储库:它使用原始工作树的存储库,方法是创建一个名为.git的文件,而不是一个名为.git的目录。

(The actual repository acquires, at the point of git worktree add , a lot of state files to track the existence of this added work-tree. The added work-tree requires adding a new index, new HEAD , and so on, all of which are dedicated to the new work-tree and separate from the index and HEAD and so on for the primary work-tree, which is still sitting next to the main repository. Note that if you later copy the actual repository using the above tar trick, it will still think it has these added work-trees. If they do still exist, that's fine; if not, git worktree prune will make the copied repository update its notion of how the outside world looks.) (实际存储库在git worktree add处获取了很多 state 文件来跟踪这个添加的工作树的存在。添加的工作树需要添加一个新的索引,新的HEAD等等,所有的它们专用于新的工作树,并与索引和HEAD等用于主工作树,主工作树仍然位于主存储库旁边。请注意,如果您稍后使用上述tar技巧复制实际存储库,它仍然会认为它有这些添加的工作树。如果它们仍然存在,那很好;如果不存在, git worktree prune将使复制的存储库更新其外部世界外观的概念。)


1 The bug is that git gc failed to look in the added HEAD and index and such files. 1错误是git gc未能查看添加的HEAD和索引等文件。 This means that if you:这意味着,如果您:

  • use a detached HEAD in the added work-tree, and make new commits, they get deleted (,), and在添加的工作树中使用分离的 HEAD,并进行新的提交,它们被删除 (,),并且
  • even if you don't use a detached HEAD, if you git add updated files but don't commit, any new repository-level blob objects can be deleted (!)即使您不使用分离的 HEAD,如果您git add更新的文件但不提交,则可以删除任何新的存储库级 blob 对象(!)

which results in a mess.这导致一团糟。

The standard default 14 day grace period means that if you get all your work done within 14 days and then discard the added work-tree, this bug never hits you, so if you have a Git version below 2.15, you can use git worktree add safely as long as you do everything in the added work-tree within two weeks.标准默认的 14 天宽限期意味着如果您在 14 天内完成所有工作,然后丢弃添加的工作树,则此错误永远不会影响您,因此如果您的 Git 版本低于 2.15,则可以使用git worktree add只要您在两周内完成添加的工作树的所有操作,就可以安全地进行操作。

(The bug actually bit me, though. Fortunately the added work-tree was merely an experiment that I had abandoned but had not gotten around to removing, and I was able to clean things up.) (不过,这个错误实际上咬了我。幸运的是,添加的工作树只是一个我已经放弃但还没有删除的实验,我能够清理这些东西。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM