-3

请原谅我在这里的无知... 这是背景:我创建了一个 TestScritps 目录来组织测试脚本。我将三个脚本<root dir><root dir>/TestScripts. 我一次移动一个,并在每个之后执行一次本地提交。然后我推送了所有的更改。

我去了另一台机器并执行了拉动:

$ cd cryptopp/
$ git pull
remote: Counting objects: 25, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 25 (delta 11), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (25/25), done.
From https://github.com/weidai11/cryptopp
   2ac9ea1..2a22a84  master     -> origin/master
Updating 2ac9ea1..2a22a84
Fast-forward
 TestScripts/cryptest-android.sh |   44 +
 TestScripts/cryptest-ios.sh     |   40 +
 TestScripts/cryptest.sh         | 5729 +++++++++++++++++++++++++++++++++++++++
 rijndael.cpp                    |    2 +-
 setenv-android.sh               |   85 +-
 5 files changed, 5870 insertions(+), 30 deletions(-)
 create mode 100755 TestScripts/cryptest-android.sh
 create mode 100755 TestScripts/cryptest-ios.sh
 create mode 100755 TestScripts/cryptest.sh

$ ls *.sh
cryptest-android.sh  cryptest.sh     setenv-android.sh   setenv-ios.sh
cryptest-ios.sh      rdrand-nasm.sh  setenv-embedded.sh

请注意,这些文件只是被复制的;他们没有动。

我检查了git-mv手册页,但似乎没有讨论错误的行为。

我有两个问题。为什么git mv只复制文件而不移动它们?我怎样才能使git mv表演“正常”?在这里,“通常”意味着几乎每个使用过命令行的人所期望的 - 它将文件<target location><destination location>.


这是相关的命令历史记录。

  994  rm -rf cryptopp/
  995  git clone https://github.com/weidai11/cryptopp
  996  cd cryptopp/
  997  mkdir TestScripts
  998  git mv cryptest.sh TestScripts/
  999  ls *.sh
 1000  git commit TestScripts/cryptest.sh -m "Organize test scripts (Issue 303)"
 1001  ls *.sh
 1002  git mv cryptest-ios.sh TestScripts/
 1003  git commit TestScripts/cryptest-ios.sh -m "Organize test scripts (Issue 303)"
 1004  ls *.sh
 1005  git commit
4

2 回答 2

3

从 的输出中显示的摘要中git pull,我看到这些文件没有被删除。

当你这样做时:

git commit TestScripts/cryptest.sh -m "Organize test scripts (Issue 303)"

虽然 Git 通常擅长跟踪文件移动,但在内部,移动被记录为删除一个文件并创建一个新的相同文件。您提交了新文件,而不是从原始位置删除文件,因此看起来 Git 只是复制了文件。

将来,从commit命令中省略文件名通常是个好主意:

git commit -m "Organize test scripts (Issue 303)"

您可以git status事先查看将提交的内容,并根据需要进行修改。

完整的会话可能如下所示:

$ git mv cryptest.sh TestScripts/
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        renamed:    cryptest.sh -> TestScripts/cryptest.sh

$ git commit -m "Organize test scripts (Issue 303)"
$ git status
On branch master
nothing to commit, working directory clean
$ ls cryptest.sh
ls: cannot access cryptest.sh: No such file or directory
$ ls TestScripts/cryptest.sh
TestScripts/cryptest.sh

要修复,请执行以下操作:

git rm cryptes*.sh
git commit

如果您想修复您的历史记录,您可以执行以下操作:

git rebase -i HEAD^3

并将相关提交的命令从 更改pickedit。在每一站,做:

git rm <file>
git commit --amend
git rebase --continue

<file>当前的原始文件在哪里。

请注意,这将重写您的历史记录,因此在机器之间移动时可能会导致问题。


请注意,不必删除并重新克隆 Git 存储库,因此如果您将来遇到问题,最好尝试修复根问题。(如果您需要帮助,请在此处搜索或询问!)

于 2016-09-23T18:19:54.333 回答
2

问题在于您对git commit命令的(ab)使用。

git mv确实移动了文件。说,我有一个带有单个文件的存储库,名为a,我想将其移动为b

$ git mv a b
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    a -> b

$ ls
b <-- Only b exists here, no a

移动现在记录在索引中,但未提交。要创建提交,我会:

$ git commit -m "Move a as b"

但是,您所做的是:

$ git commit b -m "Move a as b"
[master b275677] Move a as b
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b

当您将文件名作为参数时,git commit它仅包括提交中列出的文件,而不是记录当前索引。

在内部,git 不明白什么是移动。它知道创建了一个文件,并删除了另一个文件。用于显示历史记录的工具(git log例如)将这两条信息结合起来,并将文件显示为已移动。但是当你指定只有新创建的文件应该包含在提交中时,它并没有记录旧文件的删除,所以当你从另一台机器拉出时它不会显示为移动。

因此,您的问题的答案是:“为什么 'git mv' 不移动文件?如何使其“正常”运行?” - 它确实移动了一个文件,但你明确告诉 git 只提交新文件的创建,而不是旧文件的删除。要使其正常运行,请不要这样做 - 而是在git commit没有文件名作为参数的情况下发出。

于 2016-09-27T07:28:08.733 回答