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
andgit add -A
, thengit 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
. Editrefs/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.
精彩评论