【问题标题】:git pull keeping local changesgit pull 保持本地更改
【发布时间】:2012-05-11 23:42:10
【问题描述】:

我如何安全地更新(拉取)一个 git 项目,保持特定文件不受影响,即使上游发生更改?

myrepo/config/config.php

有没有办法,即使这个文件是在远程更改的,当我 git pull 时,其他所有内容都会更新,但这个文件没有改变(甚至没有合并)?

PS。我需要做我所要求的,因为我只编写基于 git 的部署脚本。我无法将配置文件更改为模板。

所以,我需要编写不会丢失本地更改内容的更新脚本。我希望有一些简单的东西:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

然后git pull

【问题讨论】:

标签: git


【解决方案1】:

有一个基于 Git stash 的简单解决方案。存储您已更改的所有内容,提取所有新内容,应用您的存储。

git stash
git pull
git stash pop

在 stash pop 中可能存在冲突。在您描述的情况下,config.php 实际上会发生冲突。但是,解决冲突很容易,因为您知道放入存储库中的内容就是您想要的。这样做:

git checkout --theirs -- config.php

【讨论】:

  • 那个 git checkout --theirs 命令非常混乱。它做了一次我想要的,另一次做了一些非常糟糕的事情。有什么好的文档吗?
  • 是的,有时“他们的”和“我们的”会让人混淆。在 git merge 'ours' 中是当前工作目录中的内容。但是对于git rebase(或git rebase -onto),含义可以互换。
  • git stash , git pull , git stash apply 您可以使用以下命令删除存储:git stash drop 成功合并更改后
  • git 的问题是你必须了解它要做什么。 git 的另一件事是,即使对于聪明的人来说,通常也很难理解 git 将要做什么。
  • 您应该检查是否有任何东西可以存放。否则,您会从较早的 git stash 中弹出隐藏的更改。
【解决方案2】:

如果您的 repo 中有一个文件应该由大多数 pullers 自定义,则将该文件重命名为 config.php.template 并将 config.php 添加到您的 .gitignore

【讨论】:

  • 也检查this answer,您可以使用.gitattributes 在合并时始终保留您的更改。
  • 这更像是我需要的。模板是一个优雅的解决方案,但恐怕我不能使用它,因为我只是在编写部署脚本。
【解决方案3】:

更新:这确实回答了所提出的问题,但我认为 KurzedMetal's answer 确实是您想要的。

假设:

  1. 你在分支master
  2. 上游分支是master in origin
  3. 您没有未提交的更改

....你可以这样做:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

如果您需要经常这样做,您可以为此创建一个别名。请注意,如果您对 config/config.php 有未提交的更改,这会将它们丢弃。

【讨论】:

    【解决方案4】:

    我用

    git pull -X ours
    

    这将指示 git 在合并时使用本地版本。

    【讨论】:

      【解决方案5】:

      我们也可以尝试使用 rebase 的 git pull

      git pull --rebase origin dev
      

      【讨论】:

        【解决方案6】:

        回答问题:如果你想排除某个结帐的文件,你可以使用sparse-checkout

        1. .git/info/sparse-checkout 中,定义您想要保留的内容。在这里,我们想要所有(*)但是(注意感叹号)config.php:

          /* !/config.php

        2. 告诉 git 你想考虑稀疏结帐

          git config core.sparseCheckout true

        3. 如果您已经在本地获取了该文件,请执行 git 在稀疏结帐时所做的事情(告诉它必须通过在其上设置“skip-worktree”标志来排除该文件)

          git update-index --skip-worktree config.php

        4. 享受您的 config.php 文件属于您的存储库 - 存储库中的任何更改。


        请注意,配置值不应在源代码管理中:

        • 这是一个潜在的安全漏洞
        • 它会导致类似这样的部署问题

        这意味着您必须排除它们(在第一次提交之前将它们放在 .gitignore 中),并在您签出应用的每个实例上创建适当的文件(通过复制和调整“模板”文件)

        请注意,一旦文件被 git 接管,.gitignore 将不会有任何效果。

        鉴于,一旦文件受源代码控制,您只有两个选择 ():

        • 重新设置所有历史记录以删除文件(使用git filter-branch

        • 创建一个删除文件的提交。这就像打一场失败的战斗,但是,有时候你必须忍受它。

        【讨论】:

        • 这完美!我引用手册:git read-tree and other merge-based commands (git merge, git checkout…​) can help maintaining the skip-worktree bitmap and working directory update. $GIT_DIR/info/sparse-checkout is used to define the skip-worktree reference bitmap. When git read-tree needs to update the working directory, it resets the skip-worktree bit in the index based on this file, which uses the same syntax as .gitignore files. If an entry matches a pattern in this file, skip-worktree will not be set on that entry. Otherwise, skip-worktree will be set.
        【解决方案7】:

        以防它们是本地未提交的更改,并避免在拉取时发生合并冲突。

        git stash save
        git pull
        git stash pop
        

        参考 - https://happygitwithr.com/pull-tricky.html

        【讨论】:

          猜你喜欢
          • 2020-07-29
          • 1970-01-01
          • 2016-12-11
          • 1970-01-01
          • 1970-01-01
          • 2011-05-08
          • 1970-01-01
          • 2016-07-28
          • 2016-11-02
          相关资源
          最近更新 更多