1

Say I have:

Commit 5 < HEAD
Commit 4
Commit 3
Commit 2
Commit 1

I want to Push (Commit 5) to different repo WITHOUT commits 2,3,4. Is that possible?


The reason why I need it:

I have 2 projects:

  • a starter project (Starter).
  • a project currently working on (Project-1) built on top of the (Starter).

While working on my (Project-1) I might need to do some changes to the (Starter).

What I currently have is 2 remotes in (Project-1):

  • origin pointing to the private (Project-1) repository.
  • starter pointing to the open sourced (Starter) repository.

Normally while working in (Project-1) I push all my commits to the origin master branch.

However, when I do changes to the (Starter) I commit them alone and I try to push that specific commit Commit 5 to the (Starter) repository. This is working fine! using the git push starter c78d92e32ec1a:master.

But the problem is when I push Commit 5 it also push all the previous commits (2,3,4), which in my case are related to the (Project-1).

Is it logically possible to only push specific commit even if it's not the last one. Example merge Commit 4 with (Starter) repo.

Mahmoud Zalt
  • 30,478
  • 7
  • 87
  • 83
  • 1
    Creat a new branch -> rebase -> pick commits you want to push, ignore others -> push to starter – pratZ Jun 23 '16 at 12:29

2 Answers2

2

Git is very well suited for what you're trying to achieve, however I'm afraid you should reorganize a bit.

Given the information in your question, you only have one branch and two remotes for two distinct projects. You want two different branches.

Start by checking out the most recent commit for starter that does not have parent commits of Project-1.

git checkout Commit1SHA

Create a new branch for your starter project, and set it to track starter master.

git checkout -b stmaster
git branch stmaster -u starter/master

For this time only, we can fix up the tree with a cherry pick, but things will be cleaner moving forward.

git cherry-pick Commit5SHA

Now a push will only send commits 1&5 to starter

git push

From here out, you're setup for a good rebase strategy to keep your merge lines tidy. You can continue working on Project 1, making commits, and pushing normally.

git checkout master
echo "hello world" > newfile.txt
git add .
git commit -m "create hello world"
git push

Now when you want to make changes to starter, checkout that branch for work.

git checkout stmaster
echo "starter changes" > more.txt
git add .
git commit -m "create more changes"
git push

Now rebase those changes into project 1 to keep commit lines straight.

git checkout master
git rebase stmaster
git push
Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
  • this looks very nice but it doesn't solve it 100% Dispit that when I did the cherry-pick it also published all project commits to the starter! The problem with this approach (which is very logical) is I have to do my starter changes completely separated from the project, means go to the starter branch commit there and push then go back to your project pull the updates and continue working. I would prefer if there's a way to work on the same project branch and only deliver that single commit to the starter! so far doesn't seem possible without taking all the previous commits with it – Mahmoud Zalt Jun 24 '16 at 22:59
  • Hmm, I'm not following you because `cherry-pick` will only get one commit. It's possible to [cherry-pick a range of commits](http://stackoverflow.com/a/1994491/4233593), but that's not the syntax I used. So you could continue working on Project-1, and then simply cherry-pick the commits you were interested in back to starter. – Jeff Puckett Jun 24 '16 at 23:05
  • It's weird why the cherry-pick didn't worked!! I just tried it, when I see the git log I see it got only that commit needed but when I push I see everything on the remote repository!!! why is that? should I try it again maybe I did something wrong?! – Mahmoud Zalt Jun 24 '16 at 23:30
  • Sounds like you've accidentally already pushed project 1 master to starter master. You can force push update starter with `git push starter stmaster:master -f` – Jeff Puckett Jun 25 '16 at 00:27
  • Yes I did pushed it to starter but managed to remove it immediately with `push -f`, when I tried to push the commit alone (`git push starter c78d92e32:master`) and when I tried the to use the (`cherry-pic`). Could it be since I already pushed them once, now everytime I see them no matter what I do!! or that's not related?! – Mahmoud Zalt Jun 25 '16 at 03:30
  • Brother it's finally working :D thanks for you I'll add my full answer here. Thanks again – Mahmoud Zalt Jun 25 '16 at 08:13
  • @MahmoudZalt "And I can guarantee that cherry-pick will always take the changes from all the previous commits." -- Sorry, but that's nonsense, and your own answer doesn't support this claim. It's very much unclear to me what happened and in what way your answer differs from this one. Your own answer says to just cherry-pick the commits just like this answer does. –  Jun 25 '16 at 08:31
  • I'm not saying your answer is incorrect!! it's just incomplete. I said that I guarantee cherry isn't working because when I did (git push starter starter) 4 times I kept seeing all the commits on the remote repo!!! however when I saw from another answer on stackoverlfow someone doing this (git push starter starter:feature-branch-name) I tried it and this one worked :D I don't know what's the trick there and I don't care :P I'm happy it's working so I can get back to coding. My answer follows yours just add all the steps from A to Z. Best, – Mahmoud Zalt Jun 25 '16 at 08:49
0

OMG it's working

  • select one of the following options:
    • option 1: starting from scratch
      • clone the starter - set the origin remote pointing to the starter repository url.
    • option 2: already have the project:
      • clone your project repository (git clone git@bitbucket.org:username/project.git)
  • add starter remote (git remote add starter git@github.com:username/starter.git)
  • see both remotes (git remote -v)
  • composer install “ignored by git so you will see the same file when switching branches, will read composer.json and install what’s needed"
  • add the .env file “ignored by git so you will see the same file when switching branches"
  • checkout a new “starter" branch (git checkout -b starter)
    • see both branches (git branch -v)
    • fetch everything from the starter branch (git fetch --all)
    • override the starter branch with the starter repo “have the exact copy of the starter repository in the starer branch" (git reset --hard starter/master)
    • make sure the starter branch has the latest changes from the starter repository (git pull starter master)
  • checkout the master branch (git checkout master)

    • work on the master branch normally

      • work on the project code and commit.
        • push your commits whenever you want to the remote repository of your project (git push origin master) “or to any other branch"
      • work on the starter code and commit as well "the part of the code that is reusable and beneficial for the starter to have” {just careful to never include project code with your starter commits}

        • READY TO SEE THE MAGIC!

          • checkout the starter branch (git checkout starter)
          • update the starter from its master repository (git pull starter master)
          • cherry pick your commits from the starter “find the commits ID’s from the (git log) while you are on the master branch” (git cherry-pick 98a3d7g4h2dfs)
          • see the commits are all good and ready to push (git log)
          • push the starter to a new branch on its repository (git push starter starter:feature-branch-name) “important to push to a branch, not to master directly"
          • from github create a PR and merge it anytime you want
          • if you merged in the previous step then do pull the merge commit (git pull starter master)
    • (optional) merge the starter with the project using any of these options:
      • option 1: merge and keep the project changes (git merge -X ours starter)
      • option 2: merge and overwrite your project with the starter (git merge -X theirs starter)
      • option 3: merge and solve the conflict manually (git merge starter)
Mahmoud Zalt
  • 30,478
  • 7
  • 87
  • 83