开发者

git-p4 cloned repo contains mixed filename case -- how to fix?

I imported a large repo using git-p4, and discovered that I have some strangely mixed-case filenames, e.g.:

dirA/DIRb/file1.txt

and then other files like so:

DIRa/dirB/FILE2.txt

and so on. These get entered into the repo this way because git-p4 uses fast-import. This causes Git to mysteriously claim 开发者_JAVA技巧that there are untracked directories, which are definitely not untracked, and have no new files in them. I discovered from reading this question:

git still untracked after add

and specifically slayerIQ's answer, that this can be fixed by renaming the dirs in question to have the matching case. And indeed, in a few cases where files had only a single case format, this fixed it. But for the mixed up ones like I mentioned above, it does nothing. This sort of listing confirms my suspicions regarding the case:

git ls-tree --name-only -r branch

I've considered using history rewriting to try to fix it, but that seems awfully heavyweight and I'm a bit hesitant to go there unless I have to (the tree is ~25K files). On the other hand, I do "git status" on a clean tree and get a list of about 35 "untracked" paths. So it's sort of untenable.

I'm able to do a git-p4 clone from scratch if I need to, but I suspect the mixed case paths are coming from Perforce itself. SmartGit doesn't have this problem with the tree, and copying the exact tree to a new repo works fine (since it's added correctly).

Any ideas on how to proceed?

Thanks :)


I went ahead and tried git filter-branch --tree-filter "" HEAD but that didn't do anything. Maybe there is a prettier way to do this with that, that I missed. (My git-fu is weak.)

This is ugly, ugly, ugly, but I found at least one way to do it:

  • git-p4 rebase to get everything up to date.

  • Copy the .git to another directory.

  • Switch to that new directory and update the tree with git reset --hard.

  • Delete that shiny .git you just copied over. There is now a pristine tree with the latest Perforce check-in.

  • git init and git add -A, then git commit, to make an initial check-in on a new tree. For the commit message, imitate git-p4's initial check-in message:

Initial import of //depot/ from the state at revision #head

[git-p4: depot-paths = "//depot/": change = 58840]

  • Of course update 58840 to whatever was your last revision before, and your depot path to whatever is appropriate. (Looking at the commit log in the other tree will tell you everything you need to know.)

  • git gc after that if you don't want things to be terribly slow.

You should now have a basic, non-git-p4 tree. We also need to set up the remote refs. I'm sure there is a clever git way of doing this, but I don't know it, so I will tell you what I did.

  • git log to find our import revision. Note its SHA ID.

  • Look in your original repo's .git/refs tree. Copy .git/refs/remotes into <newrepo>/.git/refs. Edit refs/remotes/p4/master to reflect your HEAD's SHA ID.

You should now have a fully functional repo that looks to git-p4 like it checked it out itself, but with consistent casing. Of course you lost your previous local history :( but if you do this early on, it's not as big of a deal.

I'm not sure if the problem comes back over time, if git-p4 continues to use fast-import, but my tree is now showing as clean on git status when it's clean.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜