【问题标题】:Trying to git add -p <file_name> but git does nothing试图 git add -p <file_name> 但 git 什么都不做
【发布时间】:2019-02-18 03:52:32
【问题描述】:

我正在尝试使用this 来应用我所做的重大更改。我做了以下事情:

 1. git pull (before I started working)
 2. changed some code
 3. git diff > ~/my_diff
 4. git stash
 5. git pull
 6. git stash pop 

由于冲突而失败,所以我尝试了:

 7. cp ~/my_diff ./
 8. git add -p ~/my_diff

但我什么也没得到...该文件包含很多更改,但出于某种原因,它表明没有大块要修补。有什么问题?


这是来自 git 的确切响应:

Your branch is up-to-date with '...'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        my_diff

nothing added to commit but untracked files present (use "git add" to track)
.../trunk $ git add -p my_diff
    No changes.

这里是head -30 ~/my_diff

diff --git a/trunk/files_transfer_mgmt/inc/files_transfer_mgmt.h b/trunk/files_transfer_mgmt/inc/files_transfer_mgmt.h
index 28907bd..f108931 100644
--- a/trunk/files_transfer_mgmt/inc/files_transfer_mgmt.h
+++ b/trunk/files_transfer_mgmt/inc/files_transfer_mgmt.h
@@ -13,6 +13,7 @@
 #include "iss_api.h"
 #include "rf_termserver.h"
 #include "rf_versions_util.h"
+#include "common_apis.h"

 #ifdef __cplusplus
        extern "C" {
@@ -23,23 +24,40 @@

 #define DEVICE_SFP             "/dev/sfp"

-#define        SECONDS_TO_USECONDS(seconds)    (seconds * 1000000)
+#define SECONDS_TO_USECONDS(seconds)   (seconds * 1000000)
+
+#define DEFAULT_FTPS_ERR_LOG "FTPS_error_log_tmp.txt"

 #ifdef __cplusplus
         }
 #endif /* __cplusplus */

 void SECURE_StartFileDownloadFromHere(void * data);
+void SECURE_ZT_entry_point(void * data);
 void SECURE_StartGenericFileTransferFromHere(void * data);
 void SECURE_getDownloadStatus(int argc, char *argv[],FILE *fin, FILE *fout,pedro_callback_func_args_t *pedro);

所以你可以看到它是一个格式良好的差异文件

【问题讨论】:

    标签: git git-commit git-add


    【解决方案1】:

    要应用你的 my_diff,你应该使用 git 命令来应用补丁,如下所示,

    git 应用我的差异

    【讨论】:

    • 这个选项会导致合并冲突,我想避免它。此外,我想逐块修补文件,以确保我批准所有更改
    【解决方案2】:

    您不必在拉取之前“git diff”,只需隐藏即可。然后拉,“stash pop”,并修复冲突。 Git 不会从存储中删除您的更改,因此如果您的冲突修复失败,您可以重新开始。您应该在最后手动清空您的存储(仅在发生冲突的情况下)

    【讨论】:

    • 这对我没有帮助。我已经做了我所做的。此外,差异是为了让我可以备份,以防我彻底搞砸了
    【解决方案3】:

    git add -p 不读取补丁文件。相反,它获取一个已经在 Git 源代码控制之下的文件,并将该文件的索引版本与该文件的工作树版本进行比较。无论有什么不同,这就是git add -p 允许您以交互方式修补到索引中。

    因此,您将不得不将每个修改过的文件保存在某处,切换提交,将所有修改过的文件恢复到您的工作树中,然后然后运行git add -p (根本没有争论)。但这通常是非常错误的方法——它会丢失每个人其他的更改。

    我会推荐以下顺序,而不是这个顺序,以及为什么:

    1. git pull(在[开始工作]之前)

    将其拆分为git fetch; git merge,这样您就可以准确地知道git pull 对您做了什么。 (有人可能会说为你,但在git pull的情况下,它倾向于你而不是你。我的Git 1.5 的糟糕旧时代的经验可能会显示在这里。:-) git pull 曾经在某些极端情况下严重破坏存储库。)

    我实际上在这里使用git merge --ff-only 只是为了确保没有发生任何奇怪的事情。 (我有一个别名git mff,简称为git merge --ff-only。有时我会使用其他一些技巧,但现在已经足够了。)

    1. 更改了一些代码

    保留这部分。 :-)

    1. git diff &gt; ~/my_diff

    不要为此烦恼。相反,运行 git addgit commit。如果你在第 2 步做了很多改动,可以先新建一个分支名:

    git checkout -b mostly-ready  # or some more suitable name
    git add -u         # or `.` or `-a` if you prefer
    git status         # check for unexpected new files, or untracked files
                       # make any adjustments you like here
    git commit
    git checkout -     # go back to previous branch
    
    1. git stash

    这不再是必需的。 git stash 所做的只是在 no 分支上提交;通过执行上述操作,或更简单的git commit,您已经在某个更合适的分支上进行了提交。

    1. git pull

    将其拆分为git fetch; git merge,或者,如果您在分支本身而不是分支上进行提交,则为git fetch; git rebase。 (您可以运行 git pull --rebase 来执行 fetch-and-rebase 序列,但同样,我认为最好将这两个步骤分开。)

    1. git stash pop

    由于您没有藏匿处,所以这里没有什么可以弹出的。如果您进行了提交并使用了git rebase,则rebase 将在向前传输您的提交时产生合并冲突(如果有)。否则你的提交在你的分支mostly-ready,或者你叫什么,现在你可以运行了:

    git cherry-pick -n mostly-ready
    

    -n 告诉 Git 提交结果。这让您有机会查看并使用git add -p,如果您愿意。如果存在合并冲突,-n 是多余的,因为 Git 无论如何都无法提交结果。请注意,有一个重要的警告:一些您的更改可能已经进行。

    staged 的确切含义

    重要的是要记住,在 Git 中,每个文件都有 三个 个副本。我们以一个名为README.txt 的文件为例。三份分别是:

    • HEAD:README.txt(试试git show HEAD:README.txt)。这是文件的已提交版本,特别是当前 提交中的版本(又名HEAD 又名@)。

      这个副本被冻结成一个提交。在提交中,它是永久的(嗯,只要提交存在)并且 100% 只读。它以仅 Git 的压缩格式在内部存储——有时非常压缩。几乎没有其他程序可以处理它;它基本上是一种仅限 Git 的格式,因此您必须使用 git showgit checkout 来获取它。

    • README.txt。这是 work-tree 版本。

      这只是一个普通的文件。你可以用它做任何你喜欢的事情。 Git 并不真正关心这个副本。 Git 只是将它放入您的工作树中,以便您可以访问它并使用它。

    • :0:README.txt。这是 index 版本。

      索引,也称为暂存区,有时也称为缓存,保存着Git确实关心的版本,但是是特殊的、压缩的、仅限 Git 的格式。该文件已准备好进入您将进行的下一个提交——但与冻结的只读已提交版本不同,您可以覆盖索引副本。

      这就是git add 所做的:git add README.txt 用工作树版本README.txt 覆盖索引版本:0:README.txt。这是 Git 告诉您有 为提交暂存的更改的时候。并不是README.txt 突然出现在暂存区:它一直都在。只是现在您将修改后的 README.txt 复制到旧的 :0:README.txt 之上,现在暂存区域中的版本不同于冻结到 HEAD 提交中的版本。 p>

    所以,这里要记住的是,您必须处理您的 work-tree 文件:您可以编辑这些文件,所以您可以随意编辑。但是一旦你这样做了,你就必须复制工作树版本索引版本之上。一些 Git 命令,例如 git checkout,首先将冻结的提交版本和索引版本设置为相同。一些,如git cherry-pick,可以更改索引版本(通常同时也更改工作树版本)。使用git add 会完全覆盖索引版本。使用git reset,您可以用冻结的HEAD 版本覆盖暂存版本:

    git reset README.txt
    

    意味着HEAD:README.txt复制到:0:README.txt之上,完全不触及工作树README.txt

    当你最终运行git commit 时,它所做的非常简单:它将所有索引版本冻结到一个新的提交中。它们已经处于正确的形式,位于索引/暂存区。工作树中的文件并不重要;只有索引中的文件很重要!

    两个非常有用的git diff 表单

    跑步:

    git diff --cached
    

    比较每个文件的HEAD(冻结)版本和索引版本,并向您展示差异。这就是你即将进行的提交的不同之处。

    跑步:

    git diff
    

    将每个文件的索引(准备提交)版本与工作树版本进行比较,并向您展示差异。这就是 你可以提交的内容与 git add 的不同之处。

    跑步:

    git status
    

    为您运行这两个差异,然后向您显示不同的文件名(仅)。 HEAD 和 index 之间不同的文件已暂存,而 index 和 work-tree 之间不同的文件不会暂存。 p>

    【讨论】:

    • 感谢您的详细说明,但我现在知道如何针对新情况执行此操作,而不是如何修复当前...
    • 我使用了 git apply -3 (上演了 ok hunks,并创建了一个有冲突的交换)。似乎很容易使用
    • 顺便说一句,您也可以将--rejectgit apply 一起使用;这有时有助于减少剩余的工作量。
    • 我在-3之前试过了。拒绝说明并没有帮助我理解如何修复补丁,所以我使用 -3 来查看实际的补丁是否完成,这样更简单
    • 是的,使用 -3 通常效果更好,最好了解两者。
    猜你喜欢
    • 2011-04-04
    • 2012-07-17
    • 2013-06-02
    • 2017-02-07
    • 2019-08-16
    • 2021-06-20
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多