Search code examples
gitgit-branchgit-pushgit-commit

How do I make unpushable commits pushable?


Master Branch had commits like this : A -> B -> C(HEAD) . HEAD was at C.

What I did :

I checked out B and made commits on top of it.

Now the tree looks like this :

    A -> B -> C(master)(origin/master)
         |
         | -> B1 -> B2(HEAD)

git status on the project directory is giving me the following message :

# Not currently on any branch.
nothing to commit (working directory clean)`

So it means that B1 and B2 cannot be pushed. I got to know that this is happening because these commits doesn't exist on any branch. Now, if I switch my branch back to master will these commits be lost? I am expecting a few more commits(B3, B4 ... BN) on these unnamed branch after which I want C to come on top of it. In essence, I would like to see the master branch in this way :

    A -> B -> B1 -> B2 -> B3 -------> BN -> C(master)(origin/master)

or atleast this way :

    A -> B ---------------------> C(master)(origin/master) -> D
         |                                                    ^
         |                                                    |
         | -> B1 -> B2 -> -> ...->BN--------------------------

What options I have to accomplish this? I want to be able to save the commits in the origin.

Any suggestions/directions is appreciated.


Solution

  • Your desired outcome

    A -> B -> B1 -> B2 -> B3 -------> BN -> C(master)(origin/master)
    

    is not possible unless you can rewrite C in the remote repo; doing this would cause problems for everyone else who has done work based on C.

    The second preference

    A -> B ---------------------> C(master)(origin/master) -> D
         |                                                    ^
         |                                                    |
         | -> B1 -> B2 -> -> ...->BN--------------------------
    

    is easy: as Magnus says, you'll make your life much easier if you give B2 (or whatever is the current latest commit in your sequence) a branch name: this is just easier to remember and type than the hash, and will make sure it doesn't get garbage collected.

    git checkout -b bbranch
    
    A -> B -> C(master)(origin/master)
         |                                                    
         |                                                    
         | -> B1 -> B2 (bbranch)
    

    Now, if you want to push B1 and B2 to origin for whatever reason, you can merge and push as normal

    git checkout master
    git pull
    git merge bbranch
    
    A -> B ------> C -> D (master)
         |             /
         |            /
         | -> B1 -> B2 (bbranch)
    
    git push
    

    You can keep working on bbranch and merge again when you're done with it

    A -> B ------> C -> D -> E -> ... -> En -> F (master)
         |             /                      /
         |            /                      /
         | -> B1 -> B2 -> B3  ->  ...  -> Bn  (bbranch)
    

    Note: if you want to push your commits to origin for whatever reason, but you don't want them on master, you can simply push bbranch and it'll take your commits with it. You'll then either need to be sure that no-one else will touch bbranch, or to make your local copy a remote-tracking branch.

    Replace the merge step B2 -> D with git push origin bbranch in this case.