git checkout-当文件规范包含已删除文件时 [英] git checkout --ours when file spec includes deleted file

查看:73
本文介绍了git checkout-当文件规范包含已删除文件时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

合并时,我们会保留Maven pom.xml文件的本地版本:

When we merge we keep the local version of our Maven pom.xml files:

git merge origin/remote_branch
git checkout --ours **/pom.xml pom.xml
git add **/pom.xml pom.xml
git commit -m "Merge"

这很好用,除非已在本地分支中删除了pom.xml文件.在运行上面的命令#2之后,我们得到一个错误:

This works great except if a pom.xml file has been removed in the local branch. After running command #2 above we get an error:

d:\code>git checkout --ours **/pom.xml pom.xml
error: path 'blah/pom.xml' does not have our version

...并且在发生此错误后,下一个命令#3 git add **/pom.xml pom.xml 有效地添加了远程pom.xml文件-正是我们 don't 想要.

... and after this error the next command #3 git add **/pom.xml pom.xml effectively adds the remote pom.xml files - exactly what we don't want.

我们如何更新脚本以处理此问题?

How can we update our script to handle this?

推荐答案

如何解决错误错误:运行命令 git checkout --ours **/some_file2.xml some_file2后,路径"some/file"没有我们的版本.xml .

作为人,您需要执行以下操作.假设您运行了以下内容,正如我在此处解释和建议的那样:

As a human, you need to do the following. Let's assume you ran the following, as I explain and recommend here:

git checkout --ours -- path/to/some/dir

...而且没有用!它什么也没做.而是输出以下错误:

...and it didn't work! It didn't do anything. Instead, it output these errors:

error: path 'path/to/some/dir/file1.cpp' does not have our version
error: path 'path/to/some/dir/file2.cpp' does not have our version
error: path 'path/to/some/dir/file3.cpp' does not have our version

问题是这些文件在我们端被删除了文件,因此我们必须手动对每个文件进行 git rm :

The problem is that these are deleted files on the our side, so we must git rm each of them manually:

git rm path/to/some/dir/file1.cpp
git rm path/to/some/dir/file2.cpp
git rm path/to/some/dir/file3.cpp

# OR (same thing)
git rm path/to/some/dir/file1.cpp path/to/some/dir/file2.cpp \
path/to/some/dir/file3.cpp

现在,重新运行您的 checkout --ours 命令,它将正常运行!:

Now, re-run your checkout --ours command and it will work just fine!:

git checkout --ours -- path/to/some/dir

行!完成.

让我们在上面添加脚本.毫无疑问,有很多方法可以做到这一点,但这是我能找到的最简单的方法:

Let's script that stuff above. There are undoubtedly many ways to do this, but here's the easiest way I could find:

# 1. attempt to run `git checkout --ours` the first time,
# collecting any filenames which errored out, if any, and 
# `git rm` them all.
git checkout --ours -- path/to/some/dir \
|& gawk '{ print $3 }' | xargs git rm

# 2. Now run it again. If it worked the first time above already, 
# no big deal--running it again causes no problems. If it failed
# above though, the above command just ran `git rm` on all those
# failed files, so now this time it will succeed!
git checkout --ours -- path/to/some/dir

完成!当然,您也可以将第一次尝试的输出也存储到文件中,并且仅在第一次尝试失败时才运行第二次尝试(这意味着输出不是一个空字符串),但是我会把它留给您

Done! You could also store the output from the first attempt into a file as well, of course, and only run the 2nd attempt if the first attempt failed (meaning the output is not an empty string), but I'll leave that up to you.

示例输出:通过 git rm 删除的文件,您将看到以下输出(此处的第一行包含 $之后的实际命令 char):

Sample output: By git rming your deleted files, you'll see the following output (the first line here contains the actual command after the $ char):

$ git checkout --ours -- path/to/some/dir |& gawk '{ print $3 }' | xargs git rm
path/to/some/dir/file1.cpp: needs merge
path/to/some/dir/file2.cpp: needs merge
path/to/some/dir/file3.cpp: needs merge
rm 'path/to/some/dir/file1.cpp'
rm 'path/to/some/dir/file2.cpp'
rm 'path/to/some/dir/file3.cpp'

git checkout的

说明 –我们的-路径/到/一些/目录|&gawk'{print $ 3}'|xargs git rm :

Explanation of git checkout --ours -- path/to/some/dir |& gawk '{ print $3 }' | xargs git rm:

  1. git checkout --ours-path/to/some/dir 接受-ours 方面的所有合并冲突(在此处查看我的答案的更多信息:谁是我们"以及谁是Git所说的他们"?).
  2. |& 管道两者 stderr 输出以及 stdout 输出,因为git命令可能打印出的错误消息将发送到 stderr ,这就是我们需要传递的内容.
  3. gawk'{print $ 3}'仅打印每行的第三个空格分隔的字段,这意味着它将捕获'path/to/some/dir/file1.cpp'错误的一部分:例如,路径'path/to/some/dir/file1.cpp'没有我们的版本.
  4. |xargs git rm 将所有这些文件通过管道传递到 git rm 以便"git remove";他们.
  1. git checkout --ours -- path/to/some/dir accepts all the merge conflicts from the --ours side (read more in my answer here: Who is "us" and who is "them" according to Git?).
  2. |& pipes both the stderr output as well as the stdout output, since the error messages that may be printed out by the git command are to stderr and that's what we need to pipe.
  3. gawk '{ print $3 }'prints only the 3rd space-separated field of each row, which means it captures the 'path/to/some/dir/file1.cpp' part of error: path 'path/to/some/dir/file1.cpp' does not have our version, for instance.
  4. | xargs git rm pipes all of those files to git rm to "git remove" them.

3.完成

现在您可以添加这些自动修复的文件并继续该过程:

3. Finishing up

And now you can add these auto-fixed-up files and continue the process:

git add path/to/some/dir 
git status 

# Use the appropriate one of these based on whatever operation 
# you were in at the time when the conflicts happened.
git merge --continue 
git rebase --continue
git revert --continue
# etc.

参考文献:

  1. 对于awk/gawk:
  1. For awk/gawk:
  1. 我的 git-diffn.sh 带有行号的git diff";脚本(我永远不记得awk语法,所以我只看一下以前已知的示例,包括我自己的示例).
  2. https://en.wikipedia.org/wiki/AWK
  3. GNU AWK官方用户指南
  1. My git-diffn.sh "git diff with line numbers" script (I can never remember awk syntax so I just look at previous known examples, including my own).
  2. https://en.wikipedia.org/wiki/AWK
  3. Official GNU AWK user guide

  • 使用 |xargs git rm :可以rm几个文件吗?
  • 使用 |& 两者 stdout stderr传递给管道:

  • Using | xargs git rm: Git rm several files?
  • Using |& to pipe both stdout and stderr: Piping both stdout and stderr in bash?
  • 这篇关于git checkout-当文件规范包含已删除文件时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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