1

The git documentation mentions in several places not to rebase if the code has been pushed to a public repository. This would be a simple rule to follow if every operation which performed a rebase had the rebase command in it:

$ git rebase foobar

However, I have seen it mentioned that other commands (i.e. reset) may also perform a rebase behind the scenes. Thus, the "thall shall not rebase" rule becomes much harder to follow as the user might not know that the command that he is running will include a rebase.

How can the user know which commands perform rebases, in order to avoid them?

Edit: Here is an example of an action which, even given the accepted answer, is not clear if it is a rebase or not.

Community
  • 1
  • 1
dotancohen
  • 30,064
  • 36
  • 138
  • 197
  • `reset` doesn't perform a rebase, and the problem isn't with rebasing specifically, it's with changing history in general. But even if you don't know beforehand what is and isn't safe, `push` will normally reject anything that would change history (which you would have to override with `--force`), so you do get a notice and can then decide what you want to do. Is that good enough? –  Dec 30 '13 at 09:41
  • @hvd: Thanks. The problem with `push` is that the user will only know _after_ the rebase is done that there may be an issue. I am looking for a solution to know beforehand. – dotancohen Dec 30 '13 at 09:44
  • I recommend [this post](http://thread.gmane.org/gmane.comp.video.dri.devel/34744) by Linus Torvalds in which he explains which history is to rebase, which is not, how "your code" is different from "your history", what to merge from upstream and what to merge from downstreams. – kostix Dec 30 '13 at 10:36
  • @kostix: That is a great post, but it only tells me _what_ to rebase. It doesn't tell me which commands are liable to cause a rebase. Subtle difference there. – dotancohen Dec 30 '13 at 13:52

2 Answers2

4

As it's been pointed out in a comment, the actual issue is changing history that has been shared (eg: pushed).

For example if you have:

A -- B -- C
 \        L master | origin/master
  \ 
   -- D

an if you rebase master on commit D, you'll have

A -- B -- C
 \        L origin/master
  \ 
   -- D -- B' -- C'
                 L master

As you can see, if you push master, the current origin/master will be lost.

The same things would happend if you do git reset --hard HEAD^ since it would change

A -- B -- C
          L master | origin/master

to

A  -- B  ------ C
      L master  L origin/master

As you can see, when you know what a command is supposed to do, it's easy to understand if it will change history.

In case of doubt, after you performed an action you could visualize branches with gitk --all, to see if you local and remote branches are still in sync.

And there's a last safety net: Git will prevent you from pushing something that would change history (you could for this push (git push -f), but at least it can't happen without you knowing it).

gturri
  • 13,807
  • 9
  • 40
  • 57
1

Typically you need to read the documentation for the command you are about to use and apply some common sense while asking yourself one question:

Will this operation change the graph that is my local git repository?

If your answer is yes, you need to check if you have pushed the part that will be changed.

HonkyTonk
  • 1,961
  • 11
  • 11