简体   繁体   English

Git:将组文件从一个 Git 分支复制到另一个 Git 分支?

[英]Git: Copy a Group files from one Git Branch into Another Git branch?

How can I Copy all the files, I have changed in last 10 days, from one branch, and place them into another git branch?如何将过去 10 天内更改过的所有文件从一个分支复制到另一个 git 分支?

This locates all the files changed,这将找到所有更改的文件,

https://stackoverflow.com/a/8016702/14432516 https://stackoverflow.com/a/8016702/14432516

git log --since="10 day ago" --author="John Smith" --name-only --pretty=format: | sort | uniq

Now, trying to utilize answer below, to specify a Subset of files to copy into another git branch.现在,尝试利用下面的答案,指定要复制到另一个 git 分支的文件子集。 This answer takes All the files, not a specified group.这个答案需要所有文件,而不是指定的组。

How can I get All the files from one git branch, and put them into the current branch without merging? 如何从一个 git 分支中获取所有文件,并将它们放入当前分支而不合并?

Example: Move/Copy 25 files from Git Branch A to Git Branch B, taking the files as is, Or merge (take source).示例:将 25 个文件从 Git 分支 A 移动/复制到 Git 分支 B,按原样处理文件,或者合并(获取源代码)。 Want all the files as in Branch A.想要分支 A 中的所有文件。

Looking for a quick automated way to conduct this for 100+ files.正在寻找一种快速自动化的方法来对 100 多个文件执行此操作。

Files aren't actually in branches .文件实际上不在分支中 Files are in commits .文件在commits 中 Every commit has a full and complete copy of every file, or more precisely, every file that Git knew about at the time you (or whoever) made that commit.每个提交都有每个文件的完整副本,或者更准确地说,Git 在您(或任何人)进行提交时知道的每个文件。

Why this matters is that it makes the answer easy—or rather, mostly easy.为什么这很重要,因为它使答案变得容易——或者更确切地说,大部分是容易的。 We'll see more about this mostly part in a bit.我们稍后会看到更多关于这个主要部分的信息。

Given:鉴于:

This locates all the files [I want to copy]:这将找到所有文件 [我想复制]:

git log arguments --name-only | sort -u

you can now simply copy those files from the last commit in the sequence of commits that git log examined.您现在可以简单地从git log检查的提交序列中的最后一次提交中复制这些文件。 Since the specified arguments above didn't include any specific commit, Git started from the commit that was the HEAD commit at that time, which would be the tip commit of the branch you had checked out at that time.由于上面指定的arguments不包含任何特定的提交,因此 Git 从当时的HEAD提交的提交开始,这将是您当时检出的分支的提示提交。 For instance, let's say you had branch branch-A out.例如,假设您有分支branch-A

You might also want to, at this point, do: arguments="--since="10 day ago" --author="John Smith" --name-only --pretty=format:" files=$(git log $arguments | sort -u) echo $files此时,您可能还想这样做:arguments="--since="10 天前" --author="John Smith" --name-only --pretty=format:" files=$(git log $arguments | sort -u) echo $files

(The only reason for setting $arguments first is to make all this fit on one line in this posting, and/or to let you run git log like this more than once.) (首先设置$arguments的唯一原因是让所有这些都适合这篇文章中的一行,和/或让您像这样运行git log不止一次。)

[How do I get (those files) ready to be committed into a new commit I will make on branch-B ?] [我如何让(那些文件)准备好提交到我将在branch-B上进行的新提交?]

You'd next run:你接下来运行:

git checkout branch-B

as usual.照常。 Then, as in the better answer to the question you linked , you would use:然后,就像对您链接的问题的更好答案一样,您将使用:

git checkout branch-A -- $files

The $files variable is set from the output from the git log --name-only | sort -u $files变量是从git log --name-only | sort -u的输出中设置的git log --name-only | sort -u git log --name-only | sort -u command. git log --name-only | sort -u命令。

Mostly大多

Where the mostly comes in is that $files can have two problems:最重要的是$files可能有两个问题:

  1. Some of the file names might contain spaces.某些文件名可能包含空格。 Shells such as bash —the examples here are all sh / dash / bash compatible—treat spaces as breaking up arguments, which is why you can run git log --since=... in the first place: each of those log , --since , --name-only , and so on have to be passed to the Git command as separate arguments.bash shell——这里的例子都是 sh/dash/bash 兼容的——将空格视为分解参数,这就是为什么你可以首先运行git log --since=... :这些log每一个, --since--name-only等必须作为单独的参数传递给 Git 命令。

    But suppose that you have a file named path/to/file with spaces.ext .但是假设您有一个名为path/to/file with spaces.ext Then $files contains path/to/file with spaces.ext , which to bash, looks like you typed in path/to/file as one argument, with as a second argument, and spaces.ext as a third argument.然后$files包含path/to/file with spaces.ext ,这在bash中,看起来像您键入path/to/file作为一个参数, with作为第二个参数, spaces.ext作为第三个参数。

    If you are stuck with this situation, bash in particular has some ways to deal with it.如果坚持这样的情况,庆典特别是有一些方法来处理它。 Your best bet is to avoid spaces in file names in the first place, though.不过,最好的办法是首先避免文件名中的空格。

  2. It's possible that one of the activities on some file, that git log showed you above, is that the file got deleted in that commit.上面显示的git log文件上的活动之一可能是该文件在该提交中被删除 The --name-only option tells Git to show you only the names of files that had some change made, between the parent of the commit and the commit in question. --name-only选项告诉 Git 只显示在提交的父级和有问题的提交之间进行了一些更改的文件的名称 If the change-made was "delete the file entirely", that file isn't in the new commit, and probably isn't in the final commit either, because it probably stayed deleted.如果所做的更改是“完全删除文件”,则该文件不在提交中,也可能不在最终提交中,因为它可能一直被删除。

    The right thing to do for such a file is generally to leave it deleted.对于此类文件,正确的做法通常是将其删除。 So if you get an error about this file, just take it out of the $files set: it's not in the commit at the tip of branch_A so you can't copy it out of that commit, but you don't want to copy it out anyway.因此,如果您收到有关此文件的错误,只需将其从$files集中取出:它不在branch_A尖端的提交中,因此您无法该提交中复制它,但您不想复制反正出来。 Just leave it deleted.干脆把它删了。

Note that instead of git checkout above, you can use git restore if your Git is 2.23 or later.请注意,如果您的 Git 是 2.23 或更高版本,则可以使用git restore代替上面的git checkout 1 This isn't any better than git checkout , it's just a little clearer: the git checkout command in Git versions predating 2.23 can do one of several jobs, and in Git 2.23, those jobs were subdivided into two separate commands: git switch does about half of them, and git restore does the other roughly-half of those jobs. 1这是不见得git checkout ,它更清晰一点点git checkout中的Git版本早于2.23命令可以做的几项工作之一,并在Git的2.23,这些工作被分为两个独立的命令: git switch呢其中大约一半,而git restore完成了大约一半的工作。

(Having split the command into two, the split-up commands were then made smarter and better . So in the current versions of Git, as time goes on, git switch and git restore put together can do more than git checkout . The old git checkout continues to exist so that if you are used to it, you can keep using it. If you need some of the new abilities, though, you must switch to the new commands.) (有分裂的命令分为二,解散命令然后做出更好更智能,所以在Git中的当前版本,随着时间的推移, git switchgit restore放在一起可以做git checkout 。老git checkout继续存在,所以如果你习惯了它,你可以继续使用它。但是,如果你需要一些新的能力,你必须切换到新的命令。)


1 When using git restore , you'll want git restore --source=branch_A -iw -- $files , rather than git checkout branch_A -- $files . 1使用git restore ,您需要git restore --source=branch_A -iw -- $files ,而不是git checkout branch_A -- $files This is a little longer to type in, which can be annoying, but it has the same effect.输入的时间有点长,这可能很烦人,但它具有相同的效果。 The "smarter-ness" of git restore is that you can select whether the files go into Git's index or not, and whether they go into your working tree or not, individually. git restore的“智能”在于您可以单独选择文件是否进入 Git 的索引,以及它们是否进入您的工作树。

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

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