0

I have a branch with several commits, example:

commit40
commit39
commit38
...
commit02
commit01

How could I make a new branch using the previous one with a range of commits? let's say since commit 38 to 40

pmiranda
  • 7,602
  • 14
  • 72
  • 155
  • 1
    what do you mean by 38-40 ? where does your branch must start from ? – Dmitry Sep 29 '21 at 15:50
  • From 38. I want to ignore the previous commits that were added by merging another branch that has some code that I don't need in the new branch. There was a "merge with" in between 38 and 30 (example) that added a lot of code that I don't need in the new branch – pmiranda Sep 29 '21 at 15:53
  • 2
    Maybe this can help you: [Git create branch from range of previous commits?](https://stackoverflow.com/questions/9853681/git-create-branch-from-range-of-previous-commits) – JK97Tae Sep 29 '21 at 15:54
  • 1
    @pmiranda git is a [Merkle Structure](https://en.wikipedia.org/wiki/Merkle_tree), so later commits depend on previous ones; are you trying to start a new branch without the older history or to simply omit a range? (is reverting them sufficient, or should they be eliminated?) I believe I may cover what you're looking for in my answer to [How to revert multiple git commits?](https://stackoverflow.com/a/68639668/4541045) in such a case – ti7 Sep 29 '21 at 15:56
  • 1
    Conceptually, a branch is several commits. Technically, it is just a pointer to a single commit. (Humans tend to view the branch as the commit plus all its ancestors). So....the concept of using a range of commits for a branch is somewhat meaningless. – William Pursell Sep 29 '21 at 16:00

3 Answers3

1

You can use cherry-pick technique. https://www.atlassian.com/git/tutorials/cherry-pick

Dave Runner
  • 226
  • 1
  • 5
  • I'm doing that right now, starting with the oldest one, but I'm talking about 250 commits, and after each cherry-pick I have to solve some conflicts, I wonder if there's a way to select a range – pmiranda Sep 29 '21 at 15:52
  • there will be no conflicts if you're really starting a _new_ branch; are you trying to bring commits present in one branch into another which both exist and have different commits? – ti7 Sep 29 '21 at 15:53
  • you can use GUI Tools like SourceTree instead of using CLI – Dave Runner Sep 29 '21 at 15:54
  • @ti7 - what do you mean by starting a new branch ? new branch can be started only from some other branch meaning it will have all the commits – Dmitry Sep 29 '21 at 15:56
  • @Dmitry you can start a branch from "nothing" (breaking history from other branches) and then begin at any commit state as if it was the first commit, though this will cause trouble later it is sometimes desirable (though I would question if it's not better to simply start a new repository) – ti7 Sep 29 '21 at 15:57
  • @ti7 please educate me on how to start branch from nothing ? – Dmitry Sep 29 '21 at 15:59
  • @Dmitry `git checkout --orphan ` is sufficient! https://stackoverflow.com/a/12543340/4541045 – ti7 Sep 29 '21 at 16:07
  • @ti7 sounds interesting, have not seen it before. however, I think it is a bit better to start from some point, to help git to do any future merges so that git could know what has been already done. it is hard to deal with two independent branches that have no common history when it comes to merges. – Dmitry Sep 29 '21 at 16:11
1
  1. checkout a new branch from commit37

    git checkout -b <new_branch_name> <commit37>

  2. delete all content, and commit it.

    rf -rm ./*; git add . ; git commit -m "cleanup";

  3. cherry-pick commits from 38-40

    git cherry-pick commit37..commit40

in the cherry pick command commit37 is not included.

Dmitry
  • 353
  • 2
  • 8
0

Based on a comment from OP, which includes this sentence:

There was a "merge with" in between 38 and 30 (example) that added a lot of code that I don't need in the new branch...

I think what might work best for you is to have a branch that has commits 1-30, and then 38-40. You can instead do a similar process without having any of the previous commits 1-38, however, the closer you can get to the state you want, the better, so it's best to "skip" the fewest commits possible in order to avoid future conflicts. Given that, here's how to simply omit commits 31-37:

git fetch
git switch -c new-branch <commit30>
git merge <commit37> --strategy=ours # this "skips" commits 31-37
git merge <commit40> -X theirs

Adding -X theirs to the last merge lessens the chances of having conflicts, but you still may have them if files were added or deleted, and also edited. At least you'll only have them one time, rather than on a per commit basis (such as with rebase or cherry-picking a range).

TTT
  • 22,611
  • 8
  • 63
  • 69