emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: VC mode and git


From: Mike Gerwitz
Subject: Re: VC mode and git
Date: Mon, 30 Mar 2015 03:54:55 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sat, Mar 28, 2015 at 12:15:59 -0400, Richard Stallman wrote:
> I have not yet seen a definitive answer about whether git reset is a
> reliable fix for that.

If a push fails, that does not necessarily indicate a "bad state"---it
simply represents that your history is different than what the remote
server has, and that the tip of the branch you are pushing to cannot
simply be "fast-forwarded" to your commit.

After a failed push, you are in no different state than you were before
the push (aside from a possibly puzzled mental state).

In your case, since you just want to commit and push in one operation,
you likely want to run `git pull --rebase`, which would get those
changes and then automatically re-commit your work on top of them, as if
you had those changes all along.  You could then push.  So, something
like:

  # commit all changes and attempt to push, pulling in changes if
  # necessary and re-pushing; on failure, restore to previous state with
  # changes uncomitted
  git commit -am Foo \
    && {
      git push \
        || {
          { git pull --rebase || handle-pull-conflicts; } \
            && git push;
        }
    } \
    || {
      git reset --soft HEAD^
      echo 'Commit failed.'
    }

But what if rebasing fails?  Then you are left resolving a conflict
before you can attempt the push operation again.  I do not know how you
would want to handle this.  `handle-pull-conflicts` might simply perform
a `git rebase --abort` and exit with a non-zero status, or it may open a
UI/shell to help resolve changes.  If you are pushing after every
change, this amounts to correcting a single commit, so it might be worth
having VC maintain the state here, allow you to correct your commit, and
then the vc-next-action would be to run `git rebase --continue` after
adding the files that conflicted.

This will be how the majority of Git users will resolve rejected pushes.

Does that make sense?

  [Aside: `git pull` without `--rebase` performs a `git fetch && git
  merge whatever-branch-you-are-tracking`, which has the unfortunate
  side-effect of creating a merge commit if histories are different;
  this muddies up history.  `git pull --rebase` performs `git fetch &&
  git rebase whatever-branch-you-are-tracking`.  The difference in the
  two styles of conflicts here is that, with rebasing, since you are
  re-committing each and every changeset, you may get multiple
  conflicts on any number of commits, whereas a merge will give you a
  single conflict that must be resolved at once.  The benefit of
  rebasing is that it gives you a clean history and does not produce an
  unnecessary merge conflict which you would then push to origin, akin
  to leaving a bag of poop on origin's doorstep.]

For other users, it may represent a wholly different problem.  For
example, if I were to push to GNU ease.js' repo and get that message,
that would be a problem, since that means that someone has committed to
my repository without my permission.  An automatic pull and re-push
would be bad in this case, since that makes it look like I'm okay with
that.

A failed push could also mean that you are tracking the wrong
branch, or pushing to the wrong repository.  Git allows you to set a
"tracking branch", which can be anything---a local branch, a remote
branch, or a branch in an entirely different repository, local or
remote.  Further, you can override the tracking branch by specifying
which remote to push to as part of the `push` command.

In your case, you'd always want to respect the tracking branch and
assume that there are no problems pushing, since you use only one
remote, and the tracking branch is always a branch of the same name on
origin.

A failed push could also mean that someone rudely rewrote history on the
remote branch (using `git push --force`) and someone needs a talkin' to.

- -- 
Mike Gerwitz
Free Software Hacker | GNU Maintainer
http://mikegerwitz.com
FSF Member #5804 | GPG Key ID: 0x8EE30EAB
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJVGQFQAAoJEPIruBWO4w6r9lMP/j9jILNs178Ty6iF5TqZapjU
LBpLANcEra5P2hKQ9qZXnOIuibysTXMTdMGRhwYnK/A/zPxNpsBXhDYvY9ELZTw4
CHDxGqdGxWXHC42qGRA+x7pcpw7WhO6DTmml3ovRXnp1QFkoZvHNwgShVg4hOteS
EZM/93NBo6C4YYLSfiCo4FedcYQ/xY29IfHQcLmjLSmOJ6PaQzuEUPVJwq8bZkjf
i4RI077FOzwbglHOc+rUWSBHTU+pzJUUS0kPClik4dveKtbN2Bl568PGGwPCyp6F
SXAlKy5RDRwBHD+CfHL9EO1Y6x+RTde04tBz0TJqP1GpBH+uIm9+wyR3Kbm/I8G9
ijdLhOSmHtlgs3nl1NF5KzwqQlvYogl2egUWpjLpLQSnzEV6k591PMSlHiVg8xNz
C/spyvOvWxqNEIw6OyYgrw2e3KbXG50kCJ79Z/0e11cG+xMoeFDL+C2Ovt/iiz/Y
f+91mJAE++58hSNXLKz0hLepTnVuHtDD5enmw8CsLrA92HVDjgs9pyr50IFagwZq
WqLKkvzo84mRZufYCTzIc7gjd0EMvPb/a0XYl3vec42Gul6J6Bb84c3ZuGGCMw5Y
UFB/tznEtdGwCxW8qiYhfLVvu6ig7WXpEz2l6A0k+HsMCWgVlDV0ztPQ2wC+2/LK
QnDA5hLak+2nZQ/U8sWV
=61Yc
-----END PGP SIGNATURE-----



reply via email to

[Prev in Thread] Current Thread [Next in Thread]