Git 结帐和合并而不触及工作树

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1402993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:50:23  来源:igfitidea点击:

Git checkout and merge without touching working tree

git

提问by djpohly

Say I have a feature branch, into which I merge upstream changes prior to pushing my changes back:

假设我有一个功能分支,在将我的更改推回之前,我将上游更改合并到其中:

git branch feature1
... [edit my code]
... [commit]
git fetch origin master
git merge fetch_head [or rebase]
... [resolve conflicts]
... [build and test code]

At this point I wish to push my changes. The normal way of doing this would be:

在这一点上,我希望推动我的更改。这样做的正常方法是:

git checkout master [changes a bunch of working tree files]
git merge feature1  [changes the same files right back]

This works fine, but will make the (date-checking) compiler think that a whole bunch of files are dirty and needs a rebuild even though the contents are the same. Is there a way to checkout-and-merge that leaves the working tree unchanged in this case?

这工作正常,但会使(日期检查)编译器认为一大堆文件是脏的,即使内容相同也需要重建。在这种情况下,有没有一种检查和合并的方法可以使工作树保持不变?

Something like:

就像是:

git checkout master --merge-branch feature1

EDIT:

编辑:

I am only talking about fast forward merges that by definition would not change the state of the files.

我只是在谈论根据定义不会改变文件状态的快进合并。

采纳答案by JasonWoof

[Edit] This is only a partial solution / workaround. See the actual answer by @djpohly below.

[编辑] 这只是部分解决方案/解决方法。请参阅下面@djpohly 的实际答案。

Firstly, you can push from anywhere. Doesn't matter what you have checked out, or whether the commits you want to push are in master.

首先,您可以从任何地方推送。无论您已签出什么,或者您要推送的提交是否在 master 中。

git push REMOTE_REPO feature1:master

see git help push

git help push

Hint: git push remoteRepo localRef:remoteRef

暗示: git push remoteRepo localRef:remoteRef

As for bringing master to where you are now without fiddling with your working copy... You can force it like so:

至于将 master 带到你现在所在的位置而无需摆弄你的工作副本......你可以像这样强制它:

# (while still on feature1 branch)
git checkout -B master origin/master

But this does a hard reset on master. ie it doesn't check for fast-forward.

但这对 master 进行了硬重置。即它不检查快进。

回答by djpohly

A simple and safe way to do this—without a push or a forced update—is to fetch feature1 into master:

一种简单而安全的方法——无需推送或强制更新——是将 feature1 提取到 master 中:

(feature1)$ git fetch . feature1:master
From .
   4a6000d..8675309  feature1   -> master

The trick is using .to get the localfeature1 ref. This is safer than forcibly updating the master branch, since it ensures the update is a fast-forward. (See the <refspec> parameter in the git-fetch documentationfor details.)

诀窍是使用.获取本地feature1 ref。这比强制更新 master 分支更安全,因为它确保更新是快进的。(有关详细信息,请参阅git-fetch 文档中的 <refspec> 参数。)

Now that feature1 and master are the same, switching between them will not touch any files:

现在 feature1 和 master 是一样的,在它们之间切换不会触及任何文件:

(feature1)$ git checkout master
Switched to branch 'master'
(master)$

回答by Jakub Nar?bski

There is no way that merge (or rebase) can work without touching the working directory (and index), as there can be merge conflicts that have to be resolved using working directory (and/or index).

合并(或变基)无法在不触及工作目录(和索引)的情况下工作,因为可能存在必须使用工作目录(和/或索引)解决的合并冲突。

You can always have another clone (perhaps using alternates, or symlinking objects directory, to save disk space), or another working directory with contrib/workdir/git-new-workdir. Or use a tool such as ccache.

您始终可以拥有另一个克隆(可能使用备用目录或符号链接对象目录以节省磁盘空间),或另一个带有contrib/workdir/git-new-workdir. 或者使用诸如ccache 之类的工具。

Edit:nowadays git worktreeis a part of core Git, no need for external tools (at least since git version 2.6.0).

编辑:现在git worktree是核心 Git 的一部分,不需要外部工具(至少从 git 版本 2.6.0 开始)。

回答by z0r

If you only care about a couple of files and you're using Unix, you can change manually fix the mtime after the fact using touch -d <timestamp>. Make sure you use ls --full-timeto get the timestamp, as the default display lacks precision.

如果您只关心几个文件并且您使用的是 Unix,则可以在事后使用touch -d <timestamp>. 确保使用ls --full-time获取时间戳,因为默认显示缺乏精度。

For example, imagine you're using Docker to build an image for a Python-based web app. If the requirements.txtfile changes it takes a long time to rebuild, because it has to download a bunch of 3rd-party libraries and compile them. Simply reset that file's mtime after merging:

例如,假设您正在使用 Docker 为基于 Python 的 Web 应用程序构建映像。如果requirements.txt文件发生变化,重建需要很长时间,因为它必须下载一堆 3rd-party 库并编译它们。合并后只需重置该文件的 mtime:

ls -og --full-time src/requirements.txt
# -rw-r--r-- 1 282 2015-11-04 20:03:28.918979065 +0400 src/requirements.txt

git checkout master
git merge --no-ff feature-foo

touch src/requirements.txt -d "2015-11-04 20:03:28.918979065 +0400"