【问题标题】:How to preview git-pull?如何预览 git-pull?
【发布时间】:2010-09-15 20:49:55
【问题描述】:

有可能吗?

基本上,有一个远程存储库,我只使用:

git pull

现在,我想预览一下这种拉动会发生什么变化(差异),而无需触及我身边的任何东西。原因是我拉的东西可能不是“好”的,我希望其他人在使我的存储库“脏”之前修复它。

【问题讨论】:

  • 你的编辑很奇怪。执行“git fetch”不会以任何方式改变您的工作树,因此您是否有未提交的本地更改并不重要。而且还不清楚您要撤消提取的哪一部分,因为它不会触及您的工作树。
  • 感谢 dkagedal,我在完全理解 Git 的工作原理之前写了这篇文章。我删除了那个编辑。
  • 每个人(包括 OP)都求助于“git fetch”是你想要的。但是,如果您逐字逐句地回答问题怎么办。例如,您想避免出于奇怪的原因进行提取,例如写保护磁盘或磁盘空间不足的风险?例如。一个可能会向您发送数 GB 数据的混乱存储库...
  • 我意识到这是一个老问题,但标题令人困惑,尤其是“不做 fetch”。我认为在写这篇文章时,有一个关于 fetch 的假设被证明是不正确的。现在编辑问题标题是否有意义? (我建议简单地删除“不进行获取”。)

标签: git version-control


【解决方案1】:

下面这个有用的命令是我从这个链接https://gist.github.com/jtdp/5443297 中挑选出来的。感谢https://gist.github.com/jtdp

git fetch origin

# show commit logs of changes
git log master..origin/master

# show diffs of changes
git diff master..origin/master

# apply the changes by merge..
git merge origin/master

# .. or just pull the changes
git pull

【讨论】:

    【解决方案2】:

    13 年后,你现在有一个 prefetch 任务在 "git maintenance"(man)

    预取任务使用来自所有已注册远程的最新对象更新对象目录。

    对于每个遥控器,运行一个git fetch 命令。
    refmap 是自定义的,以避免更新本地或远程分支(refs/headsrefs/remotes 中的分支)。
    相反,远程参考存储在 refs/prefetch/<remote>/
    另外,标签没有更新。

    这样做是为了避免破坏远程跟踪分支
    最终用户希望这些 ref 保持不动,除非他们启动 fetch。

    但是,使用预取任务,已经获得了完成稍后真正提取所需的对象,因此真正的提取会更快。
    在理想情况下,它只是对一堆远程跟踪分支的更新,而没有任何对象传输。

    而且你也可以这样做,因为 Git 2.32(2021 年第二季度)git fetch --prefetch,再次不修改你的最后一次获取状态。

    commit 32f6788commit cfd781ecommit 2e03115(2021 年 4 月 16 日)和 commit a039a1f(2021 年 4 月 6 日)Derrick Stolee (derrickstolee)
    (由 @987654329 中的 Junio C Hamano -- gitster -- 合并@,2021 年 4 月 30 日)

    fetch:添加--prefetch选项

    协助人:Tom Saeger
    协助人:Ramsay Jones
    签字人:Derrick Stolee

    “预取”维护任务将使用 --prefetch 选项,而不是通过命令行显式发送 refspec。
    目的是修改 refspec 以将所有结果放在 refs/prefetch/ 而不是其他任何地方。

    创建辅助方法filter_prefetch_refspec() 以修改给定的refspec 以适应预取任务的预期规则:

    • 保留了否定的 refspec。
    • 没有目的地的 Refspecs 被移除。
    • 来源以“refs/tags/”开头的 Refspec 将被移除。
    • 其他参考规范放在“refs/prefetch/”中。

    最后,我们添加了“force”选项,以确保根据需要替换预取引用。

    有一些有趣的案例值得测试。

    此更改的早期版本从删除 refspec 项并将剩余条目下移的循环中删除了“i--”。
    这允许一些参考规范不被修改。
    第一个 --prefetch 测试的微妙之处在于,refs/tags/* refspec 直接出现在 refs/heads/bogus/* refspec 之前。
    如果没有“i--”,此排序将删除“refs/tags/*”引用规范,并保留最后一个未修改,将结果放在“refs/heads/*”中。

    可能有一个空的 refspec。
    这种情况通常发生在用户想要获取特定标签或分支的源以外的遥控器上。
    为了正确测试这种情况,我们需要进一步删除本地分支的上游远程。
    因此,我们正在测试一个将被删除的 refspec,没有任何东西可以获取。

    fetch-options 现在包含在其man page 中:

    --prefetch

    修改配置的 refspec 以将所有 refs 放入 refs/prefetch/ 命名空间。

    【讨论】:

      【解决方案3】:

      如果您不希望 git-fetch 更新您的本地 .git,只需将您的本地 repo 复制到临时目录并在那里拉取即可。这是一个简写:

      $ alias gtp="tar -c . | (cd /tmp && mkdir tp && cd tp && tar -x && git pull; rm -rf /tmp/tp)"
      

      例如:

      $ git status
      # On branch master
      nothing to commit (working directory clean)
      
      $ gtp
      remote: Finding sources: 100% (25/25)
      remote: Total 25 (delta 10), reused 25 (delta 10)
      Unpacking objects: 100% (25/25), done.
      From ssh://my.git.domain/reapO
         32d61dc..05287d6  master     -> origin/master
      Updating 32d61dc..05287d6
      Fast-forward
       subdir/some.file       |    2 +-
       .../somepath/by.tes    |    3 ++-
       .../somepath/data      |   11 +++++++++++
       3 files changed, 14 insertions(+), 2 deletions(-)
      
      $ git status
      # On branch master
      nothing to commit (working directory clean)
      
      $ git fetch
      remote: Finding sources: 100% (25/25)
      remote: Total 25 (delta 10), reused 25 (delta 10)
      Unpacking objects: 100% (25/25), done.
      From ssh://my.git.domain/reapO
         32d61dc..05287d6  master     -> origin/master
      
      $ git status
      # On branch master
      # Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
      #
      nothing to commit (working directory clean)
      

      【讨论】:

      • 'gtp'需要在.git所在的本地repo的根目录下执行。
      【解决方案4】:

      在执行git fetch 之后,执行git log HEAD..origin/master 以显示您最后一次常见提交和源主分支之间的日志条目。要显示差异,请使用git log -p HEAD..origin/master 显示每个补丁,或使用git diff HEAD...origin/master(三个点而不是两个点)显示单个差异。

      通常不需要撤消提取,因为执行提取只会更新 remote 分支,而不会更新 您的 分支。如果您不准备在所有远程提交中进行拉取和合并,您可以使用git cherry-pick 仅接受您想要的特定远程提交。稍后,当您准备好获取所有内容时,git pull 将合并到其余提交中。

      更新:我不完全确定您为什么要避免使用 git fetch。 git fetch 所做的只是更新远程分支的本地副本。此本地副本与您的任何分支都没有任何关系,并且与未提交的本地更改没有任何关系。我听说有人在 cron 作业中运行 git fetch,因为它非常安全。 (不过,我通常不建议这样做。)

      【讨论】:

      • 我想我在阅读文档时错过了“与我的分支无关”的那部分。谢谢。
      • 出于某种原因,这对我不起作用。我尝试了 git diff HEAD...origin/master 并且当我执行“pull origin master”时它没有列出任何更改,它会获取并合并更改。那是因为我使用 git remote add 设置了远程存储库吗?
      • @screenm0nkey:我不知道(不知道更多信息)。如果您仍然不确定,我建议您打开一个新问题来询问此问题。
      • 什么对我有用(在 git fetch 之后):git log origin/master
      • git diff ...@{u}git diff HEAD...origin/master 相同,如果 origin/master 是上游分支
      【解决方案5】:

      我可能会迟到,但这件事困扰了我太久。 根据我的经验,我宁愿查看哪些更改未决,也不愿更新我的工作副本并处理这些更改。

      这在~/.gitconfig 文件中:

      [alias]
              diffpull=!git fetch && git diff HEAD..@{u}
      

      它获取当前分支,然后在工作副本和获取的分支之间进行比较。所以你应该只看到git pull带来的变化。

      【讨论】:

      • 你能把引用字符串换成HEAD..@{u}吗?它更简单,并且不需要将远程命名为“origin”或将您的分支命名为与远程相同。
      • 这是一个做得很好的别名,但我不知道你为什么要首先这样做。您将不得不在某个时候处理这​​些变化,对吧?如果您不喜欢 git pull 的合并部分,您应该可以中止它的操作……所以我不确定它的用例是什么。
      • 我知道我必须在某些时候处理这​​些更改,但正如我所写的,有时我不想这样做。我只是想知道是否会出现问题,我必须为此保留更多时间 - 或者之后我是否可以做一个git pull。我也认为这就是 op 的问题所在。
      【解决方案6】:

      我使用这两个命令,我可以看到要更改的文件。

      1. 首先执行git fetch,它会给出这样的输出(部分输出):

        ... 72f8433..c8af041 开发 -> 起源/开发 ...

      这个操作给了我们两个提交 ID,第一个是旧的,第二个是新的。

      1. 然后使用 git diff 比较这两个提交

        git diff 72f8433..c8af041 | grep "diff --git"

      此命令将列出将要更新的文件:

      diff --git a/app/controller/xxxx.php b/app/controller/xxxx.php
      diff --git a/app/view/yyyy.php b/app/view/yyyy.php
      

      例如 app/controller/xxxx.phpapp/view/yyyy.php 将被更新。

      比较两个提交使用 git diff 打印所有更新的文件 更改了行,但使用 grep 它搜索并仅获取行 包含来自输​​出的 diff --git

      【讨论】:

        【解决方案7】:

        如何将 repo 克隆到其他地方,并在真实结账和新克隆上执行 git log 以查看是否得到相同的东西。

        【讨论】:

        【解决方案8】:

        我为我创建了一个自定义 git 别名:

        alias.changes=!git log --name-status HEAD..
        

        你可以这样做:

        $git fetch
        $git changes origin
        

        这将为您提供一种在merge 之前预览更改的简便方法。

        【讨论】:

        • 你是上帝。这应该来自 git 本身
        【解决方案9】:

        您可以从远程仓库获取,查看差异,然后拉取或合并。

        这是一个名为origin 的远程仓库和一个名为master 的分支跟踪远程分支origin/master 的示例:

        git checkout master                                                  
        git fetch                                        
        git diff origin/master
        git pull --rebase origin master
        

        【讨论】:

          【解决方案10】:

          我认为 git fetch 是你要找的。

          它会提取更改和对象,而不会将它们提交到本地存储库的索引。

          它们可以稍后与 git merge 合并。

          Man Page

          编辑:进一步说明

          直接来自 Git- SVN 速成课程 link

          现在,您如何从远程存储库获取任何新更改?你去拿它们:

          git fetch http://host.xz/path/to/repo.git/ 
          

          此时它们位于您的存储库中,您可以使用以下方法检查它们:

          git log origin 
          

          您还可以区分更改。您还可以使用 git log HEAD..origin 来查看您的分支中没有的更改。然后,如果想合并它们 - 只需:

          git merge origin
          

          请注意,如果您不指定要获取的分支,它将方便地默认为跟踪远程。

          确实,阅读手册页可以让您更好地了解选项以及如何使用它。

          我只是想通过示例和记忆来做到这一点,我目前没有可以测试的盒子。你应该看看:

          git log -p //log with diff
          

          可以使用 git reset --hard (link) 撤消获取,但是您的树中所有未提交的更改以及您获取的更改都将丢失。

          【讨论】:

          • 如果你解释两件事,那可能会很好: 1. 如何撤消 git-fetch? 2. 如何查看差异?
          • 1) 撤消 git-fetch? 2) git diff HEAD..origin
          • 差异已按照 Christian 所说的完成,可以使用 git reset --hard 撤消获取,但是树中所有未提交的更改以及您获取的更改都将丢失。跨度>
          • 您在寻找git reset --soft 还是--mixed?检查手册页。
          • 如果我理解正确,则无需撤消“git fetch”,因为它不会触及您的工作副本,也不会触及您的存储库。 “git fetch”将对象和引用存储在 .git/FETCH_HEAD
          猜你喜欢
          • 2021-08-21
          • 2020-03-25
          • 2021-11-17
          • 2011-08-14
          • 2022-01-20
          • 2011-08-14
          • 2017-11-23
          • 2017-02-23
          相关资源
          最近更新 更多