1

I have a repo (bitbucket.org/mine/project) which I forked from another repo (client.com/theirs/project). I made a bunch of commits to mine and now I want to push it back to their repo. I know I can push it to the upstream repo but it seems to include all the commits. My current workaround is I have both projects cloned and copying files from my repo working dir to their repo working dir and committing. Definitely not ideal. How do I squash my commits to a single commit when I push but leave my history intact?

Attempt to illustrate the issue:

Client       ---- forked ------>      Bitbucket

their/project                         mine/project

commit #A                             commit #A
commit #B                             commit #B
commit #C                             commit #C

                                  |-  commit #1
                                  |   commit #2
                                  |   commit #3
commit #D    <----- how? ------   |-  commit #4   // I want to keep my commits

Referenced:

https://help.github.com/articles/merging-an-upstream-repository-into-your-fork/#platform-mac

Combining multiple commits before pushing in Git

YarGnawh
  • 4,574
  • 6
  • 26
  • 37
  • I think here is the answer: https://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git – Amit Bera Feb 20 '18 at 17:52
  • i saw that one and this one (https://stackoverflow.com/questions/5667884/how-to-squash-commits-in-git-after-they-have-been-pushed) but is there a way to keep my commits but combine them when pushing upstream? – YarGnawh Feb 20 '18 at 17:55

4 Answers4

0

I am not sure if there is any direct way to do that but I can suggest you a work around:

Take back up of your local branch. Let say if your branch is master and your back brach name is like master-backup. You can use below git command.

git branch master-backup

if you are on the same branch. or you can also use

git branch master-backup master

squash your commit follow the link. Now branch has single commit by combing all the commits.

git push origin master (Push your changes after squash to upstream with single commit)

git reset --hard master-backup (Get your old commits back to local master)

Amit Bera
  • 7,075
  • 1
  • 19
  • 42
0

The owner of the their/project Github repo could always do this for you by choosing to Squash and Merge the commits from your branch via the Pull Request UI:

enter image description here

Adil B
  • 14,635
  • 11
  • 60
  • 78
  • sorry for being misleading but ```their/repo``` is not actually a github repo – YarGnawh Feb 20 '18 at 18:52
  • Thanks for the clarification! The equivalent git commands are here in case that's useful: https://stackoverflow.com/a/5309051/866021 – Adil B Feb 20 '18 at 21:45
0

What works for me is to use git rebase.

You can do that with git rebase -i HEAD~3 where '3' is the HEAD position back where you will start to modify... in your example would be commit #1, because you will merge all commits into the first commit, so you can do:

git rebase -i HEAD~4 //Since you have 4 new commits done

Then you will see something like:

pick commit#1
pick commit#2
pick commit#3
pick commit#4

And you also will see the instructions below to do the rebase. So you should change that to something like:

pick commit#1
squash commit#2
squash commit#3
squash commit#4

When you apply this, you will also need to change the commit messages if you want, so you can only change the first commit message, and delete the others. At the end you will have only commit#1 with all the changes of the other further commits.

To push your commit#1 to fork repo, do:

git push origin <branch_name>
  • Note: this solution will change the original history, so I do this in another branch to keep one intact. But you can also do something with git reset ... – Dulcinea Peña Jun 25 '20 at 20:05
0

You can user git reset here

git reset --soft HEAD~N ( N is number of commits).

If you do a git status you will see all files that you changed in green.

Do a git reset again. You will see all files in red. and the branch will be uptodate with master.

Now you can do a git add . and git commit -m "<your commit message>".

This will give all changes in one commit.

Asclepius
  • 57,944
  • 17
  • 167
  • 143