0

First of all: Yes, I searched for this topic here and found a lot of answers.

None of them was what I needed for my special use case though. Before you mark this as a duplicate, read my background information please.


Background story: I’m currently working as an independent app developer and freelancer. I’ve developed a framework that I’m selling to different costumers. While developing this framework, I was using the raw source code and committed it to one of my costumers Git Repos. I never thought about selling it at that point in time. It grew in complexity and function and I’ve got a compiled version of it now.

Now I would like to be able to delete some commits without rebasing the project to remove the source code because many people would have access to it.

I searched for quite some time and couldn’t find a working solution.

Community
  • 1
  • 1
Git.Coach
  • 3,032
  • 2
  • 37
  • 54
  • 1
    So you want to delete some history, but not touch the history because others have cloned it? Do you see a contradiction? – Shahbaz Mar 14 '14 at 11:25
  • I want to delete a specific part of history in a way that it will be also removed when somebody pulls the new version of the history. Is that possible? – Git.Coach Mar 14 '14 at 11:28
  • Don't think you can do it. As you don't want to rebase and, dreadfully, many have already forked (or using it), history cannot be altered. Otherwise, I would have suggested, pull a branch prior to your oldest unwanted commit and cherry pick each commit you want to go in to it. – Bhaskar Mar 14 '14 at 11:28
  • It is a local Git in a controlled environment. Around 3-5 people are working with it. So Forking is not a problem. – Git.Coach Mar 14 '14 at 11:30
  • 1
    If the environment is small and the code is not leaked outside, you can simply tell the people to stop for a second, do your rebase/cherry-pick whatever, force push it and have them replace their branch with the new one. Make sure no one has unpushed/unmerged work. – Shahbaz Mar 14 '14 at 11:39
  • This sounds like a workaround I could live with… Do you want to add this as an answer, so that I can accept it later, if it works? – Git.Coach Mar 14 '14 at 11:48

2 Answers2

1

I have a theory that may work in your case.

Current status:

master: A ---- B ---- C ---- D ---- E ---- F 
                                           ^
                                           HEAD

Lets say, you want to delete commits B and E but keep C, D and F

Do git reset HEAD~1
git stash
Repeat previous steps till HEAD reaches A

Now master looks like this:

master: A                    Stash stack looks like:  
        ^                      B
        HEAD                   C
                               D
                               E
                               F

Checkout a new branch temp:

master: A                   Stash stack looks like
        |                      B
        |                      C
  temp: A                      D
        ^                      E
        HEAD                   F

Now, you can selectively pop each stash on temp (resolving conflicts if necessary). Note that when conflicts occur, the stash is not removed from the list. You have to explicitly call git stash drop

git stash pop stash{revision number}
git stash drop stash{revision number} if there was a conflict.
git stash drop stash {unwanted revision}

temp should look like this:

master: A 
         \
temp:     ---- C ---- D ---- F 
                             ^
                             HEAD 

Merge or rebase temp with master. The master should look like this after rebase and fast forward merge:

master: A ---- C ---- D ---- F
                             ^
                             HEAD

NOTE: In step one, another (quicker?) way to do is: git reset <SHA of A>. Then you can do interactive stashing using git stash --patch and selectively stash chunks of your changes.

Bhaskar
  • 2,549
  • 1
  • 21
  • 23
0

I think this will work

git reset HEAD^

use HEAD without --hard or --soft flag

Vinoth
  • 81
  • 5