10

我的本地存储库处于禁止我提交、存储、签出到另一个分支甚至丢弃更改的状态。所以我只是卡住了。

据我所知,我将尝试描述是什么步骤让我陷入了这种境地。

请坐。

不久前,在另一台很远很远的计算机上......根据:https ://help.github.com/articles/dealing-with-line-endings 项目中的另一个开发人员标准化crlf

在此期间(你知道,光速......)我在本地进行了一些更改,提交并拉取。

当我拉动 Git 时说:

error: Your local changes to the following files would be overwritten by merge:
    wp-config.php

wp-config.php早先使用它从索引中删除,git update-index --assume-unchanged wp-config.php因为它是一个适应每个本地环境的模板配置文件。

基础“模板”可以改变。没什么好惊讶的。这是我计划的:

  1. 重新索引wp-config.php
  2. stash我自己的配置更改
  3. pull origin master
  4. stash apply我的配置回来了

第 3 步出现问题。git pull origin master仍然引发上述错误,好像 stash 无效。

git statuswp-config.php没有为提交进行更改。藏起来后,这让我有点惊讶。

因为我隐藏了我的更改,所以我跑了git checkout -- wp-config.php......但没有任何效果!文件仍未暂存以进行提交。

由于我疯了,我创建了一个新的分支 my-config,添加并提交wp-config.php到它,然后切换回 master,删除wp-config.php(使用git rm),并合并 origin/master... 成功!

因此,既然 master 是最新且干净的,我计划在没有 Git 帮助的情况下恢复我自己的配置(手动编辑文件)。

因为我想知道发生了什么,所以我切换到 my-config 分支,并在这里尝试了一个非常简单的操作:

git stash
git stash apply

你猜怎么着?stash apply失败说:

error: Your local changes to the following files would be overwritten by merge:
    wordpress/license.txt
    wordpress/readme.html
    ...
    (all the files that where modified by the crlf conversion)

现在我被困在我的分支上(并计划看到它,法语国家会理解;))因为:

  • git stash applycommitcheckout master给出上面的错误
  • git stash产生一个隐藏条目,但不改变未暂存状态
  • 并且git checkout -- <file>都不会删除未分级的状态

我现在唯一能做的就是删除所有这些文件(使用 OS rm)才能回到主分支。

真实的故事。

我很想了解 master 分支上发生了什么,然后是 my-config 分支上发生了什么,以及是什么让我陷入这种情况(我怀疑在 crlf 转换文件上使用 stash)。

重要笔记:

  • 我在linux上运行
  • git core.autocrlf开启input
  • .gitattributes的与“处理行尾”文章中的相同
  • 我对 Git 比较陌生(使用它的第二天)

当我stash在 my-config 分支上执行时,它输出:

warning: CRLF will be replaced by LF in wordpress/license.txt.
The file will have its original line endings in your working directory.
... (one for each crlf converted file) ...
Saved working directory and index state WIP on my-config: dbf65ad my config -- should not be pushed
HEAD is now at dbf65ad my config -- should not be pushed

dbf65ad是我在 my-config 分支上所做的唯一提交)

4

3 回答 3

5

经过一番研究,我猜发生了以下情况。您的同事更改了导致第一次拉动冲突的 lineendings。

这就是为什么你隐藏你的工作,拉出东西(现在没有问题)并开始再次应用隐藏。

通过调用git stash applygit 开始递归合并隐藏的更改。

错误消息只是告诉您遇到了合并冲突。根据开发人员的存储文档,这可以通过git stash drop解决冲突后解决:

“应用 [stash] 可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要手动解决冲突,然后git stash drop手动调用。”

结论:如果必须在现有项目中完成行尾的配置,最好.gitattributes在项目文件夹中使用 a 。由于它与您的 line-ending-change-commit 一起分发,因此可以避免将您当前的工作切换到新的规范化标准的麻烦。

更改项目和 .gitattributes 中的行尾

根据您的开发人员文档,.gitattributes您可以通过以下步骤更改所有文件(在活动分支中)的行尾:

$ echo "<<filepattern>> eol=lf" >>.gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

替换<<filepattern>>为与您的源文件匹配的模式 - 在您的情况下为 python-files (此-description*.py给出了一个很好的模式解释)。.gitignore

如果您要添加多个文件模式,您可以在.gitattributes.

注意:由于第二步需要删除.git/index(这是特定于分支的),因此必须在您要保留的每个分支中完成。

如果你有很多分支要处理,你可以考虑编写一个简短的脚本来遍历你的 git 分支

于 2014-05-08T13:45:35.043 回答
1

重置本地模块的最佳方法是使用

git clean -f -x -d

这有效地删除了对本地模块的所有未跟踪更改,并将其恢复为“香草”状态。

-f干净的文件。
-x.gitignore 通常忽略的清理文件。
-d干净的目录。

现在运行git reset --hard origin/<BRANCH_NAME>。这会将您的分支重置为远程状态。

git status此时应该告诉你:

# On branch master
nothing to commit (working directory clean)

如果您隐藏了实际更改,那么您应该能够git stash apply正确地将它们放回原处。

如果git stash show stash@{0}显示的更改比您预期的要多,您可以应用您想要查看的更改git checkout stash@{0} -- <filename>

希望这可以帮助

于 2013-06-18T16:02:41.957 回答
0

首先,关于 GitHub 帮助页面,我强烈建议设置:

git config --global core.autocrlf false

让 eol 修改保留到.gitattributes文件中的显式声明而不是全局魔术规则:保持core.autocrlf为 false

其次,您可以查看是否在git stashwith上观察到相同的 eol 修改git update-index --skip-worktree

于 2013-06-18T18:44:13.867 回答