如何追溯添加提交到Git存储库? [英] How to retroactively add commits to a Git repository?

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

问题描述

我正在创建一个将第三方库移植到另一个平台的模块。我的模块的版本匹配它所包装的lib的版本。



对于这个问题,假设lib在版本10上,因此我的模块



Git refs看起来像这样:

  master === HEAD === v10(tag)

然而,出于兼容性原因,我希望如果我提交 v9 ,它将成为新的版本8和9的包装。



HEAD ,但我希望 HEAD 保持 v10 。我只想通过 $ b

  //切换到 v9 版本9 
git checkout v9

有没有办法做到这一点?



注意,我有点像git noob。我听说过重新装修和樱桃采摘,但我不太了解他们。接受的答案将提供解决方案以及解释。

解决方案

不寻常/不清楚,主要是因为它似乎没有在Git Way/查看源代码控制的上下文中设置。例如,Git中的Heads有不止一个含义......它并不是像SVN那样的意思。这点我会回头来看,但现在,我将尝试解决将代码库的以前版本添加到Git仓库的问题。



如何在Git中追溯添加提交



您至少有两个选择:


  1. 将代码库的以前版本添加为孤立的独立分支。这不是我推荐的,因为根据我的经验,孤立分支机构在工作副本之间切换效率低下,可能是因为结帐操作无法访问共同的祖先,

  2. 您可以将以前的版本添加为孤立分支,然后重新绑定最新的 v10 / master 分支,然后添加新标签。

我建议您使用选项#2 ,因为这是Stack Overflow之前解决的一个问题,它更像是The Git Way来解决这个问题:


  1. git:如何插入作为第一个提交,转移所有其他?

  2. Git:如何添加提交之前首先/启动al / root commit?

特别是,我建议您按照以下基本步骤进行详细说明在这个答案中


  1. 创建您的存储库的备份副本:

      git clone original-repo backup-repo 


  2. 创建一个孤儿分支(这将是你的新根)。

      git checkout --orphan new-master firstCommitOfOldMaster 


  3. 从孤立分支中删除工作目录文件。

      git rm -rf。 


  4. 将旧的工作重新编译为 new-master

  5. c $ c $。
    $ b

      git rebase --onto new-master --root master 
     
  6. > git diff master @ {1}


无论是在将旧的主人重新绑定到新主人之前,还是之后,您都可以使用 v9 分支。 /git-scm.com/book/en/Git-Basics-Tagging#Lightweight-Tagsrel =nofollow noreferrer>轻量级标签带注释的标记
$ b

 #轻量级
$ git标签v9

#标注
$ git标签-av9-m标签​​版本9



说明on HEAD



因此,根据上下文,Git中的头有几个含义。在上下文中,您正在使用它作为提交引用< code> HEAD< / code>仅仅意味着 您目前已经签出到您的工作副本 即可。它并不意味着与SVN中的相同,即 HEAD 不代表仓库中最新的全局提交

当你在这些分支之间检查分支或提交时, HEAD 会指向你历史记录中的不同提交(有时是以前的提交),因为你正在检查你的工作副本中的不同提交。见


  1. 什么是git HEAD,正好? HEAD和ORIG_HEAD in Git

Git中还有另一个使用头部的上下文:分支机构通常存储在 .git / refs / heads / 目录下。在这种情况下,头只是指分支指针/引用,并且是分支的提示/最近的提交。您可以通过运行 git show-ref

  git show -ref 
35ec88f1c5b319b7ca08f5d3dca3cafdebddecd4 refs / heads / awesome-feature
ea112e91953e02f9c6dcc7b9470b8bdf0a69a3eb refs / heads / epic-feature
a9874fd23f67c245fadd23bef449971fa7338755 refs / heads / master

在这里你可以看到我有3个分支头/提示/引用: master 分支, awesome-feature 分支,以及 epic-feature 分支。在每个分支的左边,您会看到分支当前指向的完整提交,即该分支的最近提交。



rebase



首先,让我先说您应该学习 rebase 。期。我认为它是Git中最基本,最重要,最强大的工具,如果你不使用它,那么你就不会有效地使用Git。因此,学会以交互方式和非交互方式学习rebase。



因此,我不会详细讨论 git rebase 的作品,因为有大量的在线资源可以解释它(我会列出它们),而且这个答案已经非常长。



但简而言之,rebase允许你以任何你可能想要的方式重写你的历史。它需要一组提交,并且 将这些提交的副本 复制到历史记录中的任何位置。所以这就是我上面提出的解决方案所做的,它将使用旧的 v10 历史记录,并在新的 v9

资源库



这里有用于了解更多关于rebase的优秀资源。请记住,您始终可以创建一个完整的 .txt 文件或任何您想要的练习Git回购,然后练习分支,重新绑定和合并:


  1. Git Tools - 重写历史记录

  2. git-rebase(1)手册页

  3. 了解Git Branching ,请参阅Interactive Rebase演示。
  4. 代码学校课程Git Real,第6课


I am creating a module that ports a third party lib to another platform. The version of my module matches the version of the lib that it wraps.

For the purposes of this question, let's say that the lib is on version 10, therefore my module is also on version 10.

Git refs look like this:

master === HEAD === v10 (tag)

However, for compatibility reasons, I wish to create versions 8 and 9 of the wrapper as well.

If I commit v9, it will become the new HEAD, but I want HEAD to stay on v10. I just want v9 to be available option via

// switch to version 9
git checkout v9

Is there anyway to do this?

Note, I'm sort of a git noob. I've heard of rebasing and cherry picking, but I don't understand either of them very well. The accepted answer will provide a solution as well as an explanation.

解决方案

The question is a little unusual/unclear, mostly because it doesn't seem to be set in "The Git Way"/context of looking at source control. "Heads" in Git have more than one meaning...it doesn't mean the same thing like it does in SVN, for example. This is a point I will come back to later, but for now, I will attempt to address what seems to be the issue of adding previous versions of a code base to a Git repo.

How to retroactively add commits in Git

You have at least two options:

  1. Add previous versions of the code base as orphaned, separate branches. This is not something I recommend, because in my experience orphaned branches are inefficient to switch between in your working copy, probably because the checkout operation doesn't have access to common ancestors and stuff like that.
  2. You can add the previous versions as orphaned branches, but then rebase the newest v10/master branch on top of them, and add new tags.

I recommend you use option #2, since it's a problem that's been addressed on Stack Overflow before, and it's more of "The Git Way" to do solve this issue:

  1. git: how to insert a commit as the first, shifting all the others?
  2. Git: how to add commits before first/initial/root commit?)

In particular, I recommend you follow these basic steps that I give a detailed explanation of in this answer:

  1. Create a backup clone of your repo:

    git clone original-repo backup-repo
    

  2. Create an orphan branch (this will be your new root).

    git checkout --orphan new-master firstCommitOfOldMaster
    

  3. Remove working directory files from orphan branch.

    git rm -rf .
    

  4. Recommit older work into new-master.

  5. Rebase old master onto new-master.

    git rebase --onto new-master --root master
    

  6. Verify that the final commit is still the same.

    git diff master@{1}
    

Either before you rebase the old master onto the new master, or afterwards, you can tag your v9 branch with either a lightweight tag or an annotated tag:

# Lightweight
$ git tag "v9"

# Annotated
$ git tag -a "v9" -m "Tag version 9"

Explanation of HEAD

So "heads" in Git have several meanings, depending on context. In the context you're using it—as a commit reference—HEAD simply means the commit that you currently have checked out into your working copy. It does not mean the same thing as in SVN, i.e. HEAD does not represent the most recent global commit in a repository.

As you checkout between branches or commits along those branches, HEAD will point to different commits in your history (sometimes previous commits), because your're checking out different commits into your working copy. See

  1. What is git HEAD, exactly?.
  2. HEAD and ORIG_HEAD in Git.

There is another context in Git where "heads" are used: branches that are local to a repository are generally stored under the .git/refs/heads/ directory. In this context, "heads" just means branch pointers/references, and are the "tips"/most recent commit for a branch. You can see your local repo's branch heads/tips by running git show-ref:

git show-ref
35ec88f1c5b319b7ca08f5d3dca3cafdebddecd4 refs/heads/awesome-feature
ea112e91953e02f9c6dcc7b9470b8bdf0a69a3eb refs/heads/epic-feature
a9874fd23f67c245fadd23bef449971fa7338755 refs/heads/master

Here you can see that I have 3 branch heads/tips/references: the master branch, awesome-feature branch, and the epic-feature branch. To the left of each branch, you'll see the full commit sha that the branch currently points to, i.e. the most recent commit for that branch.

Explanation of rebase

First off, let me begin by saying that you should learn to rebase. Period. I argue that it's the most fundamental, essential, and powerful tool in Git, and that if you're not using it, then you're not using Git effectively. So learn to rebase, both interactively and non-interactively.

With that out of the way, I won't go into too much detail about how git rebase works, since there are plenty of online resources that explain it (I will list them), and this answer is already very very long.

But in a nutshell, rebase allows you to rewrite your history, in just about any way you could possibly want to. It takes a set of commits, and re-applies copies of those commits to wherever you want in your history. So that's what the solution I suggested above does, it takes your old v10 history, and recreates it on top of the new v9 history, as if that's the way the history was created all along.

Rebase resources

Here are excellent resources for learning more about rebase. Remember that you can always create a practice Git repo full of .txt files or whatever you want, and then practice branching, rebasing, and merging with it:

  1. Git Tools - Rewriting History.
  2. git-rebase(1) Manual Page.
  3. Learn Git Branching, see the Interactive Rebase demo.
  4. Code School course Git Real, lesson 6.

这篇关于如何追溯添加提交到Git存储库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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