threads / discuss / 31721

git reset respect remote repo (make git idiot proof)

Subject: git reset respect remote repo (make git idiot proof)

## tl;dr

9 messages between Oct 3, 2012 and Oct 5, 2012.

replies: 8people: 6as markdown or json

Geoffrey De Smet· Oct 3, 2012, 14:49 UTC · lore
Suppose this case:

git clone .../blessedRepo.git // do changes git commit -m"bad1" // do changes git commit -m"bad2" git reset --hard HEAD^4 // Why does it let me do this?

// I just "broke" my local repository, because if I continue

// do changes git commit -m"good1" git push origin master // fails because the history disrespects the remote repo's history

The following commands are ok to do (because I have 2 unpushed commits):
  git reset --hard^1
  git reset --hard^2
but these are not and should be prevented (unless forced):
  git reset --hard^3
  git reset --hard^4

Is there any way to make git idiot proof by enabling that the local repo should always respect the history of the remote repo (unless forced)? Is there any way to make this a default for anyone who clones our blessed repo? No one that clones our blessed repo wants to come into the situation above. And if they do, they can always force it.

Ramkumar Ramachandra· Oct 3, 2012, 14:59 UTC · re: Geoffrey De Smet · lore

Re: git reset respect remote repo (make git idiot proof)

Hi Geoffrey,
Geoffrey De Smet wrote:
Show 15 quoted lines
> [...]
> The following commands are ok to do (because I have 2 unpushed commits):
>  git reset --hard^1
>  git reset --hard^2
> but these are not and should be prevented (unless forced):
>  git reset --hard^3
>  git reset --hard^4
>
>
> Is there any way to make git idiot proof by enabling that the local repo
> should always respect the history of the remote repo (unless forced)?
> Is there any way to make this a default for anyone who clones our blessed
> repo?
> No one that clones our blessed repo wants to come into the situation above.
> And if they do, they can always force it.

This makes little sense. Which remote? What if I have multiple remotes? Which branch? (Many of my branches are behind `master`). What if I want different histories on different remotes? What about more advanced operations which implicitly 'reset' like rebase? What if I want to rewrite history?

Ram
Geoffrey De Smet· Oct 3, 2012, 15:12 UTC · re: Ramkumar Ramachandra · lore

Re: git reset respect remote repo (make git idiot proof)

Op 03-10-12 16:59, Ramkumar Ramachandra schreef:
Show 22 quoted lines
> Hi Geoffrey,
>
> Geoffrey De Smet wrote:
>> [...]
>> The following commands are ok to do (because I have 2 unpushed commits):
>>   git reset --hard^1
>>   git reset --hard^2
>> but these are not and should be prevented (unless forced):
>>   git reset --hard^3
>>   git reset --hard^4
>>
>>
>> Is there any way to make git idiot proof by enabling that the local repo
>> should always respect the history of the remote repo (unless forced)?
>> Is there any way to make this a default for anyone who clones our 
>> blessed
>> repo?
>> No one that clones our blessed repo wants to come into the situation 
>> above.
>> And if they do, they can always force it.
> This makes little sense.
> Which remote?

To all remotes which have a relationship to this repo with the -respectRemote flag. Normally, only the blessed remote will have this.

> What if I have multiple remotes?  Which branch? (Many
> of my branches are behind `master`).

Everytime a branch merges or rebases with a remote repository, it's flags the last commit of that remote repository as the pointOfNoReset commit. If local branches merge or rebase with a local branch, the pointOfNoReset commit is transitively applied (only the last one wins). git reset will fail to reset beyond the pointOfNoReset commit, unless forced.

Branches that are behind master, will have a pointOfNoReset commit in their history, if master goes forward afterwards, that won't affect those branches, not until they are merged.

>    What if I want different
> histories on different remotes?

Don't use the -respectRemote flag in the relationship between those 2 repo's.

>   What about more advanced operations
> which implicitly 'reset' like rebase?

Them too. All operations would need to follow the -respectRemote flag's limitations, unless forced.

>    What if I want to rewrite
> history?

Don't use the -respectRemote flag in the relationship between this repo and any other repo. Or force it.

>
> Ram
Phil Hord· Oct 3, 2012, 16:40 UTC · re: Geoffrey De Smet · lore

Re: git reset respect remote repo (make git idiot proof)

On Wed, Oct 3, 2012 at 10:49 AM, Geoffrey De Smet <ge0ffrey.spam@gmail.com> wrote:

Show 28 quoted lines
> Suppose this case:
>
> git clone .../blessedRepo.git
> // do changes
> git commit -m"bad1"
> // do changes
> git commit -m"bad2"
> git reset --hard HEAD^4 // Why does it let me do this?
>
> // I just "broke" my local repository, because if I continue
>
> // do changes
> git commit -m"good1"
> git push origin master // fails because the history disrespects the remote
> repo's history
>
> The following commands are ok to do (because I have 2 unpushed commits):
>  git reset --hard^1
>  git reset --hard^2
> but these are not and should be prevented (unless forced):
>  git reset --hard^3
>  git reset --hard^4
>
>
> Is there any way to make git idiot proof by enabling that the local repo
> should always respect the history of the remote repo (unless forced)?
> Is there any way to make this a default for anyone who clones our blessed
> repo?

I suppose if we go down this path we must also prevent users from having any local branches whose names match those used on the remote unless the remote branches are also ancestors of our local branch. But then we may get into trouble when we pull new branches which now conflict but previously did not.

I'm afraid this is a Pandora's box of woes.

But I feel your pain. I think the solution lies in relegating 'reset' to the plumbing or the power-user realm of commands since I feel it is quite overloaded and sometimes dangerous. There was a thread some months back heading in this direction, but I failed to keep it going.

    http://comments.gmane.org/gmane.comp.version-control.git/185825
Phil
Geoffrey De Smet· Oct 4, 2012, 08:59 UTC · re: Phil Hord · lore

Re: git reset respect remote repo (make git idiot proof)

Op 03-10-12 18:40, Phil Hord schreef:
Show 6 quoted lines
> But I feel your pain.  I think the solution lies in relegating 'reset'
> to the plumbing or the power-user realm of commands since I feel it is
> quite overloaded and sometimes dangerous.  There was a thread some
> months back heading in this direction, but I failed to keep it going.
>
>      http://comments.gmane.org/gmane.comp.version-control.git/185825
I personally use git reset a lot:
- Try an experiment
- Commit a few commits as the experiment progresses
- figure out that the experiment is a dead end
- git reset all those _local_ commits

The point is: they are local commits, so no harm done. But there's nothing preventing me from resetting pushed commits too, which would mean harm.

Junio C Hamano· Oct 5, 2012, 03:11 UTC · re: Geoffrey De Smet · lore

Re: git reset respect remote repo (make git idiot proof)

Geoffrey De Smet <ge0ffrey.spam@gmail.com> writes:
Show 17 quoted lines
> Op 03-10-12 18:40, Phil Hord schreef:
>> But I feel your pain.  I think the solution lies in relegating 'reset'
>> to the plumbing or the power-user realm of commands since I feel it is
>> quite overloaded and sometimes dangerous.  There was a thread some
>> months back heading in this direction, but I failed to keep it going.
>>
>>      http://comments.gmane.org/gmane.comp.version-control.git/185825
>
> I personally use git reset a lot:
> - Try an experiment
> - Commit a few commits as the experiment progresses
> - figure out that the experiment is a dead end
> - git reset all those _local_ commits
>
> The point is: they are local commits, so no harm done.
> But there's nothing preventing me from resetting pushed commits too,
> which would mean harm.

Even if you reset your local branch beyond the point you pushed out, no harm is caused, as "git push" will catch that mistake, e.g.

	: on 'master' that integrates with 'master' at remote
	$ git reset --hard HEAD~4
        : work work work and commit commit commit
        $ git push origin master
        ... will result in refusal due to non-fast-forward

And then you can recover from it easily; one workflow may go like this:

	: update refs/remotes/origin/master, among other things
	$ git fetch origin
        : recover the "work work ... commit commit" part
        $ git rebase origin/master

Another thing we could think about doing is to warn at the point you reset your head away. The above "reset --hard HEAD~4", before doing what it was told to do, could perform:

	git rev-list HEAD~4..HEAD

(replace "HEAD~4" with whereever you are attempting to go) and see if any of the listed commits is an ancestor of @{upstream} of the current branch. And if that is true, then your updated "reset" can issue a warning, just like "git checkout branchname" to leave the detached HEAD state gives you a friendly warning.

Dirk Heinrichs· Oct 5, 2012, 05:35 UTC · re: Geoffrey De Smet · lore

Re: git reset respect remote repo (make git idiot proof)

Am Donnerstag 04 Oktober 2012, 10:59:36 schrieb Geoffrey De Smet:
Show 5 quoted lines
> I personally use git reset a lot:
> - Try an experiment
> - Commit a few commits as the experiment progresses
> - figure out that the experiment is a dead end
> - git reset all those local commits

Hmm, what if you do your experiments on a dedicated branch? Branch deletion is "push-save", isn't it?

Bye...
	Dirk
-- 
Dirk Heinrichs <dirk.heinrichs@altum.de>
Tel: +49 (0)2471 209385 | Mobil: +49 (0)176 34473913
GPG Public Key C2E467BB | Jabber: dirk.heinrichs@altum.de
Andreas Schwab· Oct 3, 2012, 16:52 UTC · re: Geoffrey De Smet · lore

Re: git reset respect remote repo (make git idiot proof)

Geoffrey De Smet <ge0ffrey.spam@gmail.com> writes:
Show 8 quoted lines
> Suppose this case:
>
> git clone .../blessedRepo.git
> // do changes
> git commit -m"bad1"
> // do changes
> git commit -m"bad2"
> git reset --hard HEAD^4 // Why does it let me do this?
Because there is nothing wrong with that.
> // I just "broke" my local repository, because if I continue
No you didn't.
> // do changes
> git commit -m"good1"
> git push origin master // fails because the history disrespects the remote
> repo's history

You may just as well want to push it to a different branch (or even a different repository).

Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Geoffrey De Smet· Oct 4, 2012, 08:56 UTC · re: Andreas Schwab · lore

Re: git reset respect remote repo (make git idiot proof)

Op 03-10-12 18:52, Andreas Schwab schreef:
Show 21 quoted lines
> Geoffrey De Smet <ge0ffrey.spam@gmail.com> writes:
>
>> Suppose this case:
>>
>> git clone .../blessedRepo.git
>> // do changes
>> git commit -m"bad1"
>> // do changes
>> git commit -m"bad2"
>> git reset --hard HEAD^4 // Why does it let me do this?
> Because there is nothing wrong with that.
>
>> // I just "broke" my local repository, because if I continue
> No you didn't.
>
>> // do changes
>> git commit -m"good1"
>> git push origin master // fails because the history disrespects the remote
>> repo's history
> You may just as well want to push it to a different branch (or even a
> different repository).

In most cases (probably more than 90%?), the developer will want to get his changes into the remote branch where it came from.

What do you think of the -respectRepository flag idea? If you want to push to different branches/repo's you can not use it, turn it off or -force those commands.

A remote repository can be optionally flagged with -respectRepository. That means that git should prevent the user from making local changes in the history that will prevent a normal push to that remote repository.

If a remote repository is flagged as such, git keeps track of a "pointOfNoReset" commit: Every time a branch merges or rebases with a remote repository, it's flags the last commit of that remote repository as the pointOfNoReset commit. If local branches merge or rebase with a local branch, the pointOfNoReset commit is transitively applied (only the last one wins). git reset will fail to reset beyond the pointOfNoReset commit, unless forced. git rebase and other git commands will also fail accordingly, unless forced.

>
> Andreas.
>

← back to recent threads