1

I have looked through a lot of the rebase answers and articles and nothing seems to do what I want to to.

I have a project:

startCommit(c1)-->c2-->c3-->c4-->c5-->c6-->c7-->c8-->c9-->c10 (current)

this is creating a huge bloat when I want to run mulitiple instances of the project. (the .git directory is over 30 gigs, while the project besides the .git is only about 12g.

So what I want to say is

hey git, i don't ever want to go back in time beyond c6. So I want something that looks like:

c6-->c7-->c8-->c9-->c10 (current)

Now, rebase sounds like the right answer, but no matter how many ways i've tried it, it brings up conflicts and asks for resolutions. This doesn't make sense to me - because I know i can "checkout c6" with no issues. And as far as I understand (maybe wildly wrong), c7 onward are just deltas on the snapshot that would be at c6. C7 doesn't need to know how i got to c6 right?

I'm getting a lot of conflict pauses in the rebase, and based on the nature of the files (unity scene files), I can't just resolve them on the spot. Essentially what I'd want it to do during this rebase automatically is:

Let's say there is a conflict squashing 1234 with 5 for whatever reason. I don't care what you do, but the result of the squash should be what i see if I were to checkout c5.

So yea, I don't understand why there are conflicts at all unless Git is trying to somehow store the individual changes every step of the way into a form of commit (doesn't make sense how this would be). I don't care about changes before c6.. so how do I go about creating

c6-->c7-->c8-->c9-->c10 (current)

Imagine there are 1000s of commits, and 100s of conflicts that arise when I run any rebase command.

It seems like such an obvious functionality that i'm 99% sure I just misread all of the guidance online.

I've also seen many tricks of saying...seamless effortless squish up to the current branch head for this branch....but then I don't have the last 4 commits usable to me.

Roman Rekhler
  • 475
  • 6
  • 6
  • I just recently learned about [`git replace`](https://git-scm.com/book/en/v2/Git-Tools-Replace). I've never used it but maybe it could help here? – 0x5453 Feb 23 '21 at 20:43
  • 1
    Also, based on [this](https://docs.unity3d.com/Manual/TextSceneFormat.html), maybe the ultimate problem is that you are using a binary file format? Git can't efficiently store diffs for binary files like it can for text files, which may explain why your `.git` directory is so big. – 0x5453 Feb 23 '21 at 20:45

1 Answers1

1

Assuming your history is all linear, this is what I would do:

git checkout --orphan new-branch c6 # start a new orphan branch from C6
git commit -m "First commit"
git rebase --onto new-branch c6 c10

Voila! Feel free to put your old branch where the new one is and so on.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • +1, very clever! The only thing I would have done differently is the rebase. After the commit I would have `git checkout master` and from there `git rebase --onto new-branch c6`. In this way you do not end up in detached mode because `HEAD` points to the new `master`. – Marco Luzzara Feb 23 '21 at 21:36
  • just tried this, and still getting: https://pastebin.com/yG22VFz4 I did test it on a test git project so when successful it does exactly what i want. I just don't see why there are any conflicts .. – Roman Rekhler Feb 23 '21 at 21:49
  • i did keep doing checkout --theirs ...and eventually got through. Maybe a sort or rebase with always 'theirs' strategy would work ? – Roman Rekhler Feb 23 '21 at 22:00
  • welp git pull origin master From https://github.com/company/project * branch master -> FETCH_HEAD fatal: refusing to merge unrelated histories – Roman Rekhler Feb 23 '21 at 22:52
  • @RomanRekhler: that's what making an orphan branch *does:* it makes unrelated histories. You almost never really want that. (In your case, maybe you do want that, but remember, you can't mix two unrelated histories. ... well, you *can*, but it probably doesn't do what you want.) – torek Feb 23 '21 at 23:13
  • I feel like there are many cases where you want to move a project around, but for it to only have n commits from the head. Imagine it's a huge multi year project. You don't want 10000 commits on your machine. You just want the snapshot from 10 commits ago, and then the diff for each of those. Then, you want the work you do to be able to be pushed to the remote. Does this sound unreasonable / or more directly, is it impossible? – Roman Rekhler Feb 24 '21 at 03:52
  • That's your take on it. I do want to have full history of projects. Anyway, it's not like it's technically impossible.... it's just that git doesn't have a single-command way to do it..... you have to rewrite history of the branch to only keep the last X number of commits (more or less the recipe I provided) ... and that makes it mandatory to force-push on a repo. I don't know what the hassle is all about. – eftshift0 Feb 24 '21 at 14:50
  • ... also, there's the possibility to do 'shallow clones'.... from your question and from what I just said, it would be an interesting topic to be able to configure git to _automagically_ keep only the last X number of revisions from branches (so... no more rewriting **and** your _local_ repo gets to keep only the last X number of revisions in a branch... sounds like a nice feature, actually). Not that I would be too interested to use it (as I said, I like to keep full history of projects) but I guess you would take advantage of it. – eftshift0 Feb 24 '21 at 18:28