Reputation: 48023
I'm importing multiple branches from Perforce into git using git-p4
, with full history, and it's working well, except that the various branches all end up "tailless". I know exactly at which revision (both as a Perforce changelist number and now as a newly-created git revision) each of them was branched off of the main trunk, and I'd very much like to have this explicitly reflected in my new git repository, but I can't seem to figure out how to achieve it.
Specifically, after importing, if I do a git log
on any of my branches, it's always got a "last" (earliest) revision that has no parent. I'd like to rig it up so that revision has a parent which is a particular revision along master
.
Presumably I can't just nakedly splice a branch onto master
(i.e, simply set its parent
link), because git hashes reflect full history, so all the hashes along my branch are likely to need adjusting, and I'm okay with that. I probably need a rebase operation of some kind, but again, I can't seem to figure out how to do it. The things I've tried so far have all tried to "replay" changes, as if to create slightly different versions of everything, and they've led to lots of merge conflicts which I don't have time to and don't want to resolve. The contents of each revision are perfectly fine (as created by git-p4
); all I want to do is rejigger the way they're linked together.
Specifically, I want to change this:
into this:
I've looked at git-p4
's --detect-branches
option, but it doesn't look like it'll do what I want, either. If there were a way to get git p4 sync
to set a parent for the "last" revision in the branch, rather than leaving it orphaned, that'd be perfect, but I'm not seeing a way.
All details of git-p4
aside, I think what I want is (in effect) a way to force a particular revision — specifically one of these orphaned (parentless) revisions at the "tail" of one of my branches — to have a parent
link that's a SHA hash of my choosing, and then have that revision's hash (and all of its children's) recomputed to reflect it. I suppose I could put on a plumber's cap and write my own script to do this somehow, but I'm hoping there's a supported way.
Upvotes: 1
Views: 467
Reputation: 1328312
git-p4 sync
should be able to restore origin of branches correctly with Git 2.37 (Q3 2022):
See commit 944db25 (21 Mar 2022) by Kirill Frolov (kfrolov
).
(Merged by Junio C Hamano -- gitster
-- in commit 586f237, 20 May 2022)
git-p4
: fix issue with multiple perforce remotesSigned-off-by: Kirill Frolov
Single perforce branch might be sync'ed multiple times with different revision numbers, so it will be seen to Git as complete different commits.
This can be done by the following command:git p4 sync --branch=NAME //perforce/path...
It is assumed, that this command applied multiple times and perforce repository changes between command invocations.
In such situation,
git p4
will see multiple perforce branches with same name and different revision numbers.
The problem is that to make a shelve,git-p4
script will try to find "origin
" branch, if not specified in command line explicitly.
And previously script selected any branch with same name and don't mention particular revision number.
Later this may cause failure of the command "git diff-tree -r $rev^ $rev"
"(man), so shelve can't be created (due to wrong origin branch/commit).This commit fixes the heuristic by which
git p4
selects origin branch:
- first it tries to select branch with same perforce path and perforce revision,
- and if it fails, then selects branch with only same perforce path (ignoring perforce revision number).
Upvotes: 0
Reputation: 1976
From your description it looks to me that you're missing the branchList
configuration options.
Please read the Branch Detection section of git-p4 documentation for more information.
By the way, the branching algorithm depends on the initial copy operation in P4 to have been done without file changes on order to find the exact commit in the source branch where the new branch started. Otherwise, the new branch will be created on the top of the source branch and you may end up with inconsistent code.
Upvotes: 0
Reputation: 53320
You can use filter-branch to do this.
From: https://labs.consol.de/development/git/2017/09/08/reunite-separate-git-repositories.html
It's probably better these days to use https://github.com/newren/git-filter-repo - but I haven't tried that.
https://github.com/newren/git-filter-repo/blob/main/Documentation/converting-from-filter-branch.md#re-grafting-history seems like it covers this case more cleanly.
Upvotes: 1