Git mv,没有拿起重命名的文件

时间:2013-11-08 21:47:52

标签: git cakephp version-control

我运行了一个重命名了很多文件夹的脚本,我想知道它们是重命名而不是删除的。该脚本是CakePHP升级脚本。 (./Console/cake升级全部)。

git状态显示它们已被删除并添加,这意味着我将丢失所有git历史记录。为了解决这个问题,我删除了旧文件夹并添加了新文件夹,但仍然有一些文件没有被提取。

受影响的文件/文件夹是:

test becomes Test
config becomes Config
models becomes Model
libs becomes Lib
vendors becomes Vendor
controllers becomes Controller
plugins becomes Plugin
views becomes View

这就是我所做的;

git rm -r --cached tests && git add -A Test 
git rm -r --cached config && git add -A Config 
git rm -r --cached models && git add -A Model
git rm -r --cached libs && git add -A Lib

#Views doesn't work too well
git rm -r --cached views
git add -A View

rm -r --cache controllers
git add -A Controller/

除了v​​iews文件夹外,几乎所有工作都有效。这是一些输出。您可以看到一些已被重新命名,但很多都被选为新文件 我有什么方法可以让git正确地选择它吗?

#   new file:   app/View/Clients/edit.ctp
#   new file:   app/View/Clients/index.ctp
#   new file:   app/View/Clients/show_spreadsheet.ctp
#   renamed:    app/views/clients/spreadsheet_url.ctp -> app/View/Clients/spreadsheet_url.ctp
#   new file:   app/View/Clients/view.ctp
#   renamed:    app/views/clients/view_spreadsheet_queue.ctp -> app/View/Clients/view_spreadsheet_queue.ctp
#   new file:   app/View/Contacts/add.ctp
#   new file:   app/View/Contacts/edit.ctp
#   new file:   app/View/Contacts/index.ctp
#   new file:   app/View/Contacts/view.ctp
#   new file:   app/View/Dashboard/index.ctp
#   new file:   app/View/Dashboard/phone_lookup.ctp
#   new file:   app/View/Dockets/index.ctp
#   new file:   app/View/Dockets/select_for_invoicing.ctp
#   new file:   app/View/Dockets/select_for_payment.ctp
#   new file:   app/View/Dockets/show_processed.ctp
#   renamed:    app/views/dockets/view_job_for_date.ctp -> app/View/Dockets/view_job_for_date.ctp
#   new file:   app/View/Elements/admin_crumb.ctp
#   renamed:    app/views/elements/buttons.ctp -> app/View/Elements/buttons.ctp
#   renamed:    app/views/elements/client_autocomplete.ctp -> app/View/Elements/client_autocomplete.ctp
#   new file:   app/View/Elements/clients/incompatibility.ctp
#   renamed:    app/views/elements/communication_log.ctp -> app/View/Elements/communication_log.ctp
#   new file:   app/View/Elements/count_header.ctp
#   renamed:    app/views/elements/csv.ctp -> app/View/Elements/csv.ctp
#   new file:   app/View/Elements/dashboard/equipment_list.ctp
#   new file:   app/View/Elements/dashboard/phone_lookup.ctp

...

2 个答案:

答案 0 :(得分:0)

  

git状态显示它们已被删除并添加,这意味着我将丢失所有git历史记录。

是的,你只需要提交。没有历史可以丢失。

答案 1 :(得分:0)

我在评论中提到的额外努力可能不值得,但是,你可以把它分成两个提交。首先,保存这些内容,使用git stash或稍后将替换的常规提交。然后,找出应该发生什么重命名,并自己做。这是一个例子......

$ mkdir /tmp/temp
$ cd /tmp/temp
$ git init
Initialized empty Git repository in /tmp/temp/.git/
$ cat > .gitignore
*.o
$ git add .gitignore
$ git commit -m initial
[master (root-commit) da5da28] initial
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
$ mkdir oldname
$ echo some contents > oldname/file; echo more contents >> oldname/file
$ echo "this file won't match" > oldname/trick
$ git add oldname; git commit -m pre-rename
[master 6be4d34] pre-rename
 2 files changed, 3 insertions(+)
 create mode 100644 oldname/file
 create mode 100644 oldname/trick

现在我们将模拟更新脚本的操作......

$ mv oldname newname
$ echo "completely replace contents too" > newname/trick
$ git rm -r --cached oldname
rm 'oldname/file'
rm 'oldname/trick'
$ git add newname
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    oldname/file -> newname/file
#   new file:   newname/trick
#   deleted:    oldname/trick
#
$ 

现在我们有类似(但很简化)的情况。 Git无法判断该目录是否只是被重命名,因为文件trick的内容也基本上被替换了。

所以让我们保存这个并通过两次提交而不是一次提交git变得更容易!

$ git checkout -b save && git commit -m 'save before splitting'
A   newname/file
A   newname/trick
D   oldname/file
D   oldname/trick
Switched to a new branch 'save'
[save 6935f96] save before splitting
 3 files changed, 1 insertion(+), 1 deletion(-)
 rename {oldname => newname}/file (100%)
 create mode 100644 newname/trick
 delete mode 100644 oldname/trick
$ 

现在我们已经准备好在两次提交中实现这一点。首先让我们在切换到save之前在我们所在的分支上恢复旧状态。

$ git checkout master
$ git mv oldname newname
$ git commit -m 'intermediate: rename files w/o modifications'
[master 7770d56] intermediate: rename files w/o modifications
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename {oldname => newname}/file (100%)
 rename {oldname => newname}/trick (100%)
$ git rm -r --cached .
rm '.gitignore'
rm 'newname/file'
rm 'newname/trick'
$ git checkout save -- .
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   newname/trick
#
$ git commit -m 'final: pick up scripted changes'
[master 8b28a2f] final: pick up scripted changes
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git branch -D save
Deleted branch save (was 6935f96).

Voila,我们已经完成了所有工作,但是通过额外的中间提交使重命名显而易见。当然,中间提交可能不正确,可测试,无论什么(可能其中的某些文件取决于旧名称和需要更改以匹配新名称)。所以这种方法有优点和缺点。 (例如,你可以做更多的工作,甚至可以在进行中间提交之前进行测试并进行git可以识别为重命名和修改操作的微小更改。)