0

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

git status 显示它们已被删除和添加,这意味着我丢失了所有 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/

除了views文件夹之外,几乎所有东西都正常工作。这是一些输出。您可以看到一些已作为重命名被拾取,但很多被拾取为新文件。
有什么办法可以让 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

...

4

2 回答 2

0

git status 显示它们已被删除和添加,这意味着我丢失了所有 git 历史记录。

是的,您只需要提交即可。历史不会丢失。

于 2013-11-08T22:53:48.870 回答
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).

瞧,我们已经完成了所有工作,但是还有一个额外的中间提交,这使得重命名变得显而易见。当然,中间提交可能不正确、可测试,无论如何(可能其中的某些文件依赖于旧名称并且需要更改以匹配新名称)。所以这种方法有利有弊。(例如,您可以做更多的工作,甚至可以在进行中间提交之前进行测试,并进行 git 可以识别为重命名和修改操作的微小更改。)

于 2013-11-09T01:58:02.517 回答