我可以运行类似于“git difftool -d”的东西吗,其中一个面是实时工作副本?

cxfofazt  于 2023-02-20  发布在  Git
关注(0)|答案(2)|浏览(128)

我了解此命令的工作原理:

git difftool -d A B

它将A和B中所有 * 不同 * 的文件的快照“ checkout ”到两个临时文件夹中,并完成必要的目录结构,然后在这两个目录中弹出difftool。
我想知道的是git是否有办法做到以下几点:

git difftool -d A <live working copy>

我理解实时工作副本将包含存储库的所有文件,而不仅仅是那些不同的文件。
这个问题背后的动机是我使用的difftool,Beyond Compare 4让我编辑文件并保存更改,它允许我比较文件(左边和右边)并将更改从一边带到另一边,甚至可以手动更正。
这将是很好的说:“让我比较它是什么之前,我开始改变,因为我需要撤销几个改变”。
大多数集成了git的IDE都允许这种部分撤销,git diff允许我使用命令行来恢复块(如果我没记错的话)。
那么,通过仔细构造git参数可以做到这一点吗?
这是在Windows 10与最新版本的git和超越比较,如果有任何问题。
请注意,如果git本身无法做到这一点,那么问题可以变成这样:我可以让git把一个特定提交和动态索引之间不同的所有文件的快照复制到一个文件夹结构中吗?如果可以,我可以很容易地创建一个git-partial-undo bash脚本来完成这个任务。
例如,如果我可以很容易地让git把下面的文件解压到一个临时文件夹中:

git diff --name-only --diff-filter=ACMRTUXB HEAD~2

src/a/b.txt
src/b/other.txt

然后,我可以很容易地弹出该文件夹和当前文件夹之间的比较工具。

icnyk63a

icnyk63a1#

我会贴出一个答案,但在我看来,这是一个可怕的答案,可能有太多的代码,我在另一端的规模“擅长bash编程”,等等。
我最后做了以下几点:
1.我计算出要与哪个提交进行比较(比较的另一边总是本地工作文件夹)

  • 我让git生成一个提交和本地文件夹之间的差异列表
  • 注意,我使用过滤器跳过了A类型的修改,因为在这种情况下,文件路径将引用本地文件夹,而不是其他提交
  • 推论;这可能对其他一些修改类型也是如此,如果遇到这种情况,我会修复它
  • 然后,我运行每个修改过的文件,并从该提交中获取一个副本,将其放入一个新的临时文件夹中的临时文件中,并完成目录结构
  • 最后,我在临时文件夹和本地文件夹的顶部弹出Beyond Compare
  • 我需要明确要求Beyond Compare只比较文件,而不显示右侧的孤立文件,否则本地文件夹将充满文件。我意识到对文件的一些修改,如添加和删除,在此设置中将没有意义,但这就是它的方式。

因此,这里的代码,读它和哭泣:

#!/bin/sh

if ! git rev-parse --git-dir > /dev/null 2>&1; then
    echo error: not in a git repository or work tree
    exit 1
fi;

COMMIT=$(git rev-parse $1)
COMMIT_NAME="Commit $1"
if [ "$COMMIT" != "$1" ]; then
    COMMIT_NAME="$COMMIT_NAME = $COMMIT"
fi
if [ -z "$COMMIT" ]; then
    if [ -z "$(git status -s)" ]; then
        echo "No changes"
        exit 0
    else
        echo "Comparing against unmodified"
        COMMIT_NAME="Unmodified"
        COMMIT=HEAD
    fi
fi

TEMPDIR=$(mktemp -d)
CHANGES=$(git diff --name-status --diff-filter=DCMRTUXB $COMMIT)
ANY_CHANGES=0
while read -r LINE;
do
    MODIFICATION=${LINE:0:1}
    if [ -z "$MODIFICATION" ]; then
        continue
    fi
    FILENAME=${LINE:2}
    TARGET=$TEMPDIR/$FILENAME
    TARGET_DIR=$(dirname "${TARGET}")
    mkdir -p $TARGET_DIR
    git show "$COMMIT:$FILENAME" > $TARGET
    ANY_CHANGES=1
done <<< $CHANGES

if [ "$ANY_CHANGES" = "1" ]; then
    BC=$(echo "/$DROPBOX/Tools/Beyond Compare 4/bcomp.exe" | sed 's/\\/\//g' | sed 's/://')
    "$BC" $TEMPDIR . //leftreadonly //title1="$COMMIT_NAME"
else
    echo "No changes detected"
fi
rm -rf "$TEMPDIR"
3j86kqsm

3j86kqsm2#

我已经用下面的方法使用了Beyond Compare,以获得我认为你想要的结果。
例如,假设我有一个git分支我想将它与master分支中的内容进行比较。
1.首先,我通过执行git merge master来获取那些更改,以确保我的分支与其他合并到master的分支保持最新。
1.我执行了一个git difftool -d master,这将创建两个独立的临时目录,master目录在左边,my分支目录在右边(在前面的某个时刻,已经通过git config...将BC.exe设置为我的difftool)。
1.我可以看到BC中临时文件夹的路径,所以我去那里压缩内容(如果我不这样做,而是尝试将BC中右边的路径指向我的分支的工作目录,左边的文件夹就会消失,因为我认为它认为diff过程已经完成,它会清理)。
1.我把压缩文件移到任何方便的地方,然后我可以使用BC来比较左边的文件夹(至少对我来说,命名为'left'很方便)和我的分支的工作目录。
因为您之前做了git merge master,所以您只需使用BC文件夹视图中的“Diffs No Orphans”按钮就可以只看到您所做的更改。

相关问题