1. 29 Oct, 2016 1 commit
    • Junio C Hamano's avatar
      push: do not use potentially ambiguous default refspec · eef2bdaa
      Junio C Hamano authored
      When the user does the lazy "git push" with no parameters with
      push.default set to either "upstream", "simple" or "current",
      we internally generated a refspec that has the current branch name
      on the source side and used it to push.
      However, the branch name (say "test") may be an ambiguous refname in
      the context of the source repository---there may be a tag with the
      same name, for example.  This would trigger an unnecessary error
      without any fault on the end-user's side.
      Be explicit and give a full refname as the source side to avoid the
      ambiguity.  The destination side when pushing with the "current"
      sent only the name of the branch and forcing the receiving end to
      guess, which is the same issue.  Be explicit there as well.
      Reported-by: Kannan Goundan's avatarKannan Goundan <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  2. 14 Jul, 2016 1 commit
  3. 25 Feb, 2016 1 commit
    • Matthieu Moy's avatar
      push: remove "push.default is unset" warning message · 2f275207
      Matthieu Moy authored
      The warning was important before the 2.0 transition, and remained
      important for a while after, so that new users get push.default
      explicitly in their configuration and do not experience inconsistent
      behavior if they ever used an older version of Git.
      The warning has been there since version 1.8.0 (Oct 2012), hence we can
      expect the vast majority of current Git users to have been exposed to
      it, and most of them have already set push.default explicitly. The
      switch from 'matching' to 'simple' was planned for 2.0 (May 2014), but
      actually happened only for 2.3 (Feb 2015).
      Today, the warning is mostly seen by beginners, who have not set their
      push.default configuration (yet). For many of them, the warning is
      confusing because it talks about concepts that they have not learned and
      asks them a choice that they are not able to make yet. See for example
      (1260 votes for the question, 1824 for the answer as of writing)
      Remove the warning completely to avoid disturbing beginners. People who
      still occasionally use an older version of Git will be exposed to the
      warning through this old version.
      Eventually, versions of Git without the warning will be deployed enough
      and tutorials will not need to advise setting push.default anymore.
      Signed-off-by: default avatarMatthieu Moy <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  4. 12 Feb, 2016 1 commit
  5. 22 Dec, 2015 1 commit
  6. 16 Dec, 2015 1 commit
  7. 04 Dec, 2015 1 commit
  8. 20 Nov, 2015 1 commit
    • Mike Crowe's avatar
      push: add recurseSubmodules config option · b33a15b0
      Mike Crowe authored
      The --recurse-submodules command line parameter has existed for some
      time but it has no config file equivalent.
      Following the style of the corresponding parameter for git fetch, let's
      invent push.recurseSubmodules to provide a default for this
      parameter. This also requires the addition of --recurse-submodules=no to
      allow the configuration to be overridden on the command line when
      The most straightforward way to implement this appears to be to make
      push use code in submodule-config in a similar way to fetch.
      Signed-off-by: Mike Crowe's avatarMike Crowe <[email protected]>
      Signed-off-by: default avatarJeff King <[email protected]>
  9. 19 Aug, 2015 2 commits
  10. 14 Mar, 2015 1 commit
  11. 17 Feb, 2015 2 commits
  12. 16 Feb, 2015 1 commit
  13. 08 Jan, 2015 1 commit
  14. 01 Dec, 2014 1 commit
    • Jeff King's avatar
      push: truly use "simple" as default, not "upstream" · 00a6fa07
      Jeff King authored
      The plan for the push.default transition had all along been
      to use the "simple" method rather than "upstream" as a
      default if the user did not specify their own push.default
      value. Commit 11037ee7 (push: switch default from "matching"
      to "simple", 2013-01-04) tried to implement that by moving
      PUSH_DEFAULT_UNSPECIFIED in our switch statement to
      fall-through to the PUSH_DEFAULT_SIMPLE case.
      When the commit that became 11037ee7 was originally written,
      that would have been enough. We would fall through to
      calling setup_push_upstream() with the "simple" parameter
      set to 1. However, it was delayed for a while until we were
      ready to make the transition in Git 2.0.
      And in the meantime, commit ed2b1829 (push: change `simple`
      to accommodate triangular workflows, 2013-06-19) threw a
      monkey wrench into the works. That commit drops the "simple"
      parameter to setup_push_upstream, and instead checks whether
      the global "push_default" is PUSH_DEFAULT_SIMPLE. This is
      right when the user has explicitly configured push.default
      to simple, but wrong when we are a fall-through for the
      "unspecified" case.
      We never noticed because our push.default tests do not cover
      the case of the variable being totally unset; they only
      check the "simple" behavior itself.
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  15. 18 Nov, 2014 1 commit
  16. 24 Oct, 2014 1 commit
  17. 15 Sep, 2014 1 commit
    • Junio C Hamano's avatar
      push: the beginning of "git push --signed" · a85b377d
      Junio C Hamano authored
      While signed tags and commits assert that the objects thusly signed
      came from you, who signed these objects, there is not a good way to
      assert that you wanted to have a particular object at the tip of a
      particular branch.  My signing v2.0.1 tag only means I want to call
      the version v2.0.1, and it does not mean I want to push it out to my
      'master' branch---it is likely that I only want it in 'maint', so
      the signature on the object alone is insufficient.
      The only assurance to you that 'maint' points at what I wanted to
      place there comes from your trust on the hosting site and my
      authentication with it, which cannot easily audited later.
      Introduce a mechanism that allows you to sign a "push certificate"
      (for the lack of better name) every time you push, asserting that
      what object you are pushing to update which ref that used to point
      at what other object.  Think of it as a cryptographic protection for
      ref updates, similar to signed tags/commits but working on an
      orthogonal axis.
      The basic flow based on this mechanism goes like this:
       1. You push out your work with "git push --signed".
       2. The sending side learns where the remote refs are as usual,
          together with what protocol extension the receiving end
          supports.  If the receiving end does not advertise the protocol
          extension "push-cert", an attempt to "git push --signed" fails.
          Otherwise, a text file, that looks like the following, is
          prepared in core:
      	certificate version 0.1
      	pusher Junio C Hamano <[email protected]> 1315427886 -0700
      	7339ca65... 21580ecb... refs/heads/master
      	3793ac56... 12850bec... refs/heads/next
          The file begins with a few header lines, which may grow as we
          gain more experience.  The 'pusher' header records the name of
          the signer (the value of user.signingkey configuration variable,
          falling back to GIT_COMMITTER_{NAME|EMAIL}) and the time of the
          certificate generation.  After the header, a blank line follows,
          followed by a copy of the protocol message lines.
          Each line shows the old and the new object name at the tip of
          the ref this push tries to update, in the way identical to how
          the underlying "git push" protocol exchange tells the ref
          updates to the receiving end (by recording the "old" object
          name, the push certificate also protects against replaying).  It
          is expected that new command packet types other than the
          old-new-refname kind will be included in push certificate in the
          same way as would appear in the plain vanilla command packets in
          unsigned pushes.
          The user then is asked to sign this push certificate using GPG,
          formatted in a way similar to how signed tag objects are signed,
          and the result is sent to the other side (i.e. receive-pack).
          In the protocol exchange, this step comes immediately before the
          sender tells what the result of the push should be, which in
          turn comes before it sends the pack data.
       3. When the receiving end sees a push certificate, the certificate
          is written out as a blob.  The pre-receive hook can learn about
          the certificate by checking GIT_PUSH_CERT environment variable,
          which, if present, tells the object name of this blob, and make
          the decision to allow or reject this push.  Additionally, the
          post-receive hook can also look at the certificate, which may be
          a good place to log all the received certificates for later
      Because a push certificate carry the same information as the usual
      command packets in the protocol exchange, we can omit the latter
      when a push certificate is in use and reduce the protocol overhead.
      This however is not included in this patch to make it easier to
      review (in other words, the series at this step should never be
      released without the remainder of the series, as it implements an
      interim protocol that will be incompatible with the final one).
      As such, the documentation update for the protocol is left out of
      this step.
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  18. 20 Jun, 2014 1 commit
    • Jeff King's avatar
      refactor skip_prefix to return a boolean · cf4fff57
      Jeff King authored
      The skip_prefix() function returns a pointer to the content
      past the prefix, or NULL if the prefix was not found. While
      this is nice and simple, in practice it makes it hard to use
      for two reasons:
        1. When you want to conditionally skip or keep the string
           as-is, you have to introduce a temporary variable.
           For example:
             tmp = skip_prefix(buf, "foo");
             if (tmp)
      	       buf = tmp;
        2. It is verbose to check the outcome in a conditional, as
           you need extra parentheses to silence compiler
           warnings. For example:
             if ((cp = skip_prefix(buf, "foo"))
      	       /* do something with cp */
      Both of these make it harder to use for long if-chains, and
      we tend to use starts_with() instead. However, the first line
      of "do something" is often to then skip forward in buf past
      the prefix, either using a magic constant or with an extra
      strlen(3) (which is generally computed at compile time, but
      means we are repeating ourselves).
      This patch refactors skip_prefix() to return a simple boolean,
      and to provide the pointer value as an out-parameter. If the
      prefix is not found, the out-parameter is untouched. This
      lets you write:
        if (skip_prefix(arg, "foo ", &arg))
        else if (skip_prefix(arg, "bar ", &arg))
      Signed-off-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  19. 04 Dec, 2013 2 commits
    • Junio C Hamano's avatar
      push: also use "upstream" mapping when pushing a single ref · fc9261ca
      Junio C Hamano authored
      When the user is using the 'upstream' mode, these commands:
          $ git push
          $ git push origin
      would find the 'upstream' branch for the current branch, and then
      push the current branch to update it.  However, pushing a single
      branch explicitly, i.e.
          $ git push origin $(git symbolic-ref --short HEAD)
      would not go through the same ref mapping process, and ends up
      updating the branch at 'origin' of the same name, which may not
      necessarily be the upstream of the branch being pushed.
      In the spirit similar to the previous one, map a colon-less refspec
      using the upstream mapping logic.
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Junio C Hamano's avatar
      push: use remote.$name.push as a refmap · ca02465b
      Junio C Hamano authored
      Since f2690487 (fetch: opportunistically update tracking refs,
      2013-05-11), we stopped taking a non-storing refspec given on the
      command line of "git fetch" literally, and instead started mapping
      it via remote.$name.fetch refspecs.  This allows
          $ git fetch origin master
      from the 'origin' repository, which is configured with
          [remote "origin"]
              fetch = +refs/heads/*:refs/remotes/origin/*
      to update refs/remotes/origin/master with the result, as if the
      command line were
          $ git fetch origin +master:refs/remotes/origin/master
      to reduce surprises and improve usability.  Before that change, a
      refspec on the command line without a colon was only to fetch the
      history and leave the result in FETCH_HEAD, without updating the
      remote-tracking branches.
      When you are simulating a fetch from you by your mothership with a
      push by you into your mothership, instead of having:
          [remote "satellite"]
              fetch = +refs/heads/*:refs/remotes/satellite/*
      on the mothership repository and running:
          mothership$ git fetch satellite
      you would have:
          [remote "mothership"]
              push = +refs/heads/*:refs/remotes/satellite/*
      on your satellite machine, and run:
          satellite$ git push mothership
      Because we so far did not make the corresponding change to the push
      side, this command:
          satellite$ git push mothership master
      does _not_ allow you on the satellite to only push 'master' out but
      still to the usual destination (i.e. refs/remotes/satellite/master).
      Implement the logic to map an unqualified refspec given on the
      command line via the remote.$name.push refspec.  This will bring a
      bit more symmetry between "fetch" and "push".
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  20. 03 Dec, 2013 1 commit
  21. 13 Nov, 2013 2 commits
  22. 13 Aug, 2013 1 commit
    • Duy Nguyen's avatar
      push: respect --no-thin · f7c815c3
      Duy Nguyen authored
      - From the beginning of push.c in 755225de, 2006-04-29, "thin" option
        was enabled by default but could be turned off with --no-thin.
      - Then Shawn changed the default to 0 in favor of saving server
        resources in a4503a15, 2007-09-09. --no-thin worked great.
      - One day later, in 9b288516 Daniel extracted some code from push.c to
        create transport.c. He (probably accidentally) flipped the default
        value from 0 to 1 in transport_get().
      From then on --no-thin is effectively no-op because git-push still
      expects the default value to be false and only calls
      transport_set_option() when "thin" variable in push.c is true (which
      is unnecessary). Correct the code to respect --no-thin by calling
      transport_set_option() in both cases.
      receive-pack learns about --reject-thin-pack-for-testing option,
      which only is for testing purposes, hence no document update.
      Signed-off-by: Duy Nguyen's avatarNguyễn Thái Ngọc Duy <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  23. 05 Aug, 2013 1 commit
  24. 29 Jul, 2013 1 commit
  25. 23 Jul, 2013 2 commits
    • Junio C Hamano's avatar
      push --force-with-lease: implement logic to populate old_sha1_expect[] · 91048a95
      Junio C Hamano authored
      This plugs the push_cas_option data collected by the command line
      option parser to the transport system with a new function
      apply_push_cas(), which is called after match_push_refs() has
      already been called.
      At this point, we know which remote we are talking to, and what
      remote refs we are going to update, so we can fill in the details
      that may have been missing from the command line, such as
       (1) what abbreviated refname the user gave us matches the actual
           refname at the remote; and
       (2) which remote-tracking branch in our local repository to read
           the value of the object to expect at the remote.
      to populate the old_sha1_expect[] field of each of the remote ref.
      As stated in the documentation, the use of remote-tracking branch
      as the default is a tentative one, and we may come up with a better
      logic as we gain experience.
      Still nobody uses this information, which is the topic of the next
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Junio C Hamano's avatar
      remote.c: add command line option parser for "--force-with-lease" · 28f5d176
      Junio C Hamano authored
      Update "git push" and "git send-pack" to parse this commnd line
      The intended sematics is:
       * "--force-with-lease" alone, without specifying the details, will
         protect _all_ remote refs that are going to be updated by
         requiring their current value to be the same as some reasonable
         default, unless otherwise specified;
       * "--force-with-lease=refname", without specifying the expected
         value, will protect that refname, if it is going to be updated,
         by requiring its current value to be the same as some reasonable
       * "--force-with-lease=refname:value" will protect that refname, if
         it is going to be updated, by requiring its current value to be
         the same as the specified value; and
       * "--no-force-with-lease" will cancel all the previous --force-with-lease on the
         command line.
      For now, "some reasonable default" is tentatively defined as "the
      value of the remote-tracking branch we have for the ref of the
      remote being updated", and it is an error if we do not have such a
      remote-tracking branch.  But this is known to be fragile, its use is
      not yet recommended, and hopefully we will find more reasonable
      default as we gain experience with this feature.  The manual marks
      the feature as experimental unless the expected value is specified
      explicitly for this reason.
      Because the command line options are parsed _before_ we know which
      remote we are pushing to, there needs further processing to the
      parsed data after we instantiate the transport object to:
       * expand "refname" given by the user to a full refname to be
         matched with the list of "struct ref" used in match_push_refs()
         and set_ref_status_for_push(); and
       * learning the actual local ref that is the remote-tracking branch
         for the specified remote ref.
      Further, some processing need to be deferred until we find the set
      of remote refs and match_push_refs() returns in order to find the
      ones that need to be checked after explicit ones have been processed
      for "--force-with-lease" (no specific details).
      These post-processing will be the topic of the next patch.
      This option was originally called "cas" (for "compare and swap"),
      the name which nobody liked because it was too technical.  The
      second attempt called it "lockref" (because it is conceptually like
      pushing after taking a lock) but the word "lock" was hated because
      it implied that it may reject push by others, which is not the way
      this option works.  This round calls it "force-with-lease".  You
      assume you took the lease on the ref when you fetched to decide what
      the rebased history should be, and you can push back only if the
      lease has not been broken.
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  26. 09 Jul, 2013 1 commit
  27. 07 Jul, 2013 1 commit
  28. 24 Jun, 2013 1 commit
    • Ramkumar Ramachandra's avatar
      push: change `simple` to accommodate triangular workflows · ed2b1829
      Ramkumar Ramachandra authored
      When remote.pushdefault or branch.<name>.pushremote is set to a
      remote that is different from where you usually fetch from (i.e. a
      triangular workflow), [email protected]{u} != origin, and push.default is set
      to `upstream` or `simple` would fail with this error:
        $ git push
        fatal: You are pushing to remote 'origin', which is not the upstream of
        your current branch 'master', without telling me what to push
        to update which remote branch.
      The very name of "upstream" indicates that it is only suitable for
      use in central workflows; let us not even attempt to give it a new
      meaning in triangular workflows, and error out as before.
      However, the `simple` does not have to share this error.  It is
      poised to be the default for Git 2.0, and we would like it to do
      something sensible in triangular workflows.
      Redefine "simple" as "safer upstream" for centralized workflow as
      before, but work as "current" for triangular workflow.
      We may want to make it "safer current", but that is a separate
      Reported-by: default avatarLeandro Lucarella <[email protected]>
      Signed-off-by: default avatarRamkumar Ramachandra <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  29. 18 Jun, 2013 1 commit
  30. 29 May, 2013 3 commits
    • Ramkumar Ramachandra's avatar
      push: make push.default = current use resolved HEAD · 0f075b22
      Ramkumar Ramachandra authored
      With this change, the output of the push (with push.default set to
      current) changes subtly from:
        $ git push
         * [new branch]      HEAD -> push-current-head
        $ git push
         * [new branch]      push-current-head -> push-current-head
      This patch was written with a different motivation. There is a problem
      unique to push.default = current:
        # on branch push-current-head
        $ git push
        # on another terminal
        $ git checkout master
        # return to the first terminal
        # the push tried to push master!
      This happens because the 'git checkout' on the second terminal races
      with the 'git push' on the first terminal.  Although this patch does not
      solve the core problem (there is still no guarantee that 'git push' on
      the first terminal will resolve HEAD before 'git checkout' changes HEAD
      on the second), it works in practice.
      Signed-off-by: default avatarRamkumar Ramachandra <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Ramkumar Ramachandra's avatar
      push: fail early with detached HEAD and current · 7b2ecd81
      Ramkumar Ramachandra authored
      Setting push.default to current adds the refspec "HEAD" for the
      transport layer to handle.  If "HEAD" doesn't resolve to a branch (and
      since no refspec rhs is specified), the push fails after some time with
      a cryptic error message:
        $ git push
        error: unable to push to unqualified destination: HEAD
        The destination refspec neither matches an existing ref on the remote nor
        begins with refs/, and we are unable to guess a prefix based on the source ref.
        error: failed to push some refs to '[email protected]:artagnon/git'
      Fail early with a nicer error message:
        $ git push
        fatal: You are not currently on a branch.
        To push the history leading to the current (detached HEAD)
        state now, use
          git push ram HEAD:<name-of-remote-branch>
      Just like in the upstream and simple cases.
      Signed-off-by: default avatarRamkumar Ramachandra <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
    • Ramkumar Ramachandra's avatar
      push: factor out the detached HEAD error message · 35ee69c0
      Ramkumar Ramachandra authored
      With push.default set to upstream or simple, and a detached HEAD, git
      push prints the following error:
        $ git push
        fatal: You are not currently on a branch.
        To push the history leading to the current (detached HEAD)
        state now, use
          git push ram HEAD:<name-of-remote-branch>
      This error is not unique to upstream or simple: current cannot push with
      a detached HEAD either.  So, factor out the error string in preparation
      for using it in current.
      Signed-off-by: default avatarRamkumar Ramachandra <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  31. 02 Apr, 2013 1 commit
    • Ramkumar Ramachandra's avatar
      remote.c: introduce a way to have different remotes for fetch/push · f24f715e
      Ramkumar Ramachandra authored
      Currently, do_push() in push.c calls remote_get(), which gets the
      configured remote for fetching and pushing.  Replace this call with a
      call to pushremote_get() instead, a new function that will return the
      remote configured specifically for pushing.  This function tries to
      work with the string pushremote_name, before falling back to the
      codepath of remote_get().  This patch has no visible impact, but
      serves to enable future patches to introduce configuration variables
      to set pushremote_name.  For example, you can now do the following in
          if (!strcmp(key, "remote.pushdefault"))
             git_config_string(&pushremote_name, key, value);
      Then, pushes will automatically go to the remote specified by
      Signed-off-by: default avatarRamkumar Ramachandra <[email protected]>
      Reviewed-by: default avatarJeff King <[email protected]>
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  32. 05 Mar, 2013 1 commit
    • Junio C Hamano's avatar
      push: --follow-tags · c2aba155
      Junio C Hamano authored
      The new option "--follow-tags" tells "git push" to push annotated
      tags that are missing from the other side and that can be reached by
      the history that is otherwise pushed out.
      For example, if you are using the "simple", "current", or "upstream"
      push, you would ordinarily push the history leading to the commit at
      your current HEAD and nothing else.  With this option, you would
      also push all annotated tags that can be reached from that commit to
      the other side.
      Signed-off-by: default avatarJunio C Hamano <[email protected]>
  33. 25 Jan, 2013 1 commit