Ilman Ilman - 1 month ago 19
Git Question

Squash arbitrary commits in a remote branch

I am a bit of a noob with Git and was tasked to clean up the history of a feature I developed recently. I have a similar setup to this fellow here. I also kind of want to accomplish the same thing, but I want to squash to specific commits. For example, if my commits are commit1, commit2, ..., commitN, I want to make it so that commit1, commit2, ... are squashed to commitX; commitX+1, commitX+2, ... are squashed to commitY; etc.

I understand that this is possible with the command

git rebase -i origin/*branch_name*


but the problem is that when I run that command, I get this:

noop

# Rebase a112005..a112005 onto a112005 (1 command(s))
...


As far as I understand, the last and the first commits should be displayed here, but it only sees the last commit. When I try to run pick or squash with any other commit it says:

error: could not apply *commit hash*... *commit message*


which obviously means that it finds the commit since it knows its message, but for some reason, it doesn't even see it as editable. Anybody have any idea how I can fix this? Also if someone recommends either a better terminal-based synchronization system for my setup or a better way of organizing my stuff, I'd be grateful.

Answer

You cannot do anything on a remote-tracking branch. In fact, you cannot be "on" a remote-tracking branch in the first place. (The git checkout command is the one that puts you "on a branch", as git status shows; but it will not put you on a remote-tracking branch, only on a local branch.)

In general, to make something happen in a Git repository, you must make it happen in your Git repository, using your branch-names.

When you want something to happen in someone else's Git repository (such as the one on origin), the way you do this is to first, get everything set up in your repository, then use git push to ask them to take your work into their repository and set one of their branch names to match.

If you ask them—the other Git that controls that other repository—to set their branch-name to point to some specific commit,1 and they agree, then, at that point, your Git will set your origin/branch-name to point to that same commit, since their Git has told yours that, yes, it is now using that particular commit for that particular branch.


1They need to have that commit, but your git push will give it to them first, if they don't already have it. That's how git push works. First, it hands over the set of objects that you have that they don't that they need in order to accept your requests; then, it hands over a series of requests: "Please set branch B1 to commit 1234567..., and/or branch B2 to commit 89abcde..., and/or set tag T to ...". Their Git obeys none, some, or all of these requests, sending either "ok" or "no, and here's why" responses for each one.

Comments