Update Git submodule to latest commit on origin

后端 未结 14 1418
清歌不尽
清歌不尽 2020-11-27 09:02

I have a project with a Git submodule. It is from an ssh://... URL, and is on commit A. Commit B has been pushed to that URL, and I want the submodule to retrieve the commit

相关标签:
14条回答
  • 2020-11-27 09:26

    Note, while the modern form of updating submodule commits would be:

    git submodule update --recursive --remote --merge --force
    

    The older form was:

    git submodule foreach --quiet git pull --quiet origin
    

    Except... this second form is not really "quiet".

    See commit a282f5a (12 Apr 2019) by Nguyễn Thái Ngọc Duy (pclouds).
    (Merged by Junio C Hamano -- gitster -- in commit f1c9f6c, 25 Apr 2019)

    submodule foreach: fix "<command> --quiet" not being respected

    Robin reported that

    git submodule foreach --quiet git pull --quiet origin
    

    is not really quiet anymore.
    It should be quiet before fc1b924 (submodule: port submodule subcommand 'foreach' from shell to C, 2018-05-10, Git v2.19.0-rc0) because parseopt can't accidentally eat options then.

    "git pull" behaves as if --quiet is not given.

    This happens because parseopt in submodule--helper will try to parse both --quiet options as if they are foreach's options, not git-pull's.
    The parsed options are removed from the command line. So when we do pull later, we execute just this

    git pull origin
    

    When calling submodule helper, adding "--" in front of "git pull" will stop parseopt for parsing options that do not really belong to submodule--helper foreach.

    PARSE_OPT_KEEP_UNKNOWN is removed as a safety measure. parseopt should never see unknown options or something has gone wrong. There are also a couple usage string update while I'm looking at them.

    While at it, I also add "--" to other subcommands that pass "$@" to submodule--helper. "$@" in these cases are paths and less likely to be --something-like-this.
    But the point still stands, git-submodule has parsed and classified what are options, what are paths.
    submodule--helper should never consider paths passed by git-submodule to be options even if they look like one.


    And Git 2.23 (Q3 2019) fixes another issue: "git submodule foreach" did not protect command line options passed to the command to be run in each submodule correctly, when the "--recursive" option was in use.

    See commit 30db18b (24 Jun 2019) by Morian Sonnet (momoson).
    (Merged by Junio C Hamano -- gitster -- in commit 968eecb, 09 Jul 2019)

    submodule foreach: fix recursion of options

    Calling:

    git submodule foreach --recursive <subcommand> --<option>
    

    leads to an error stating that the option --<option> is unknown to submodule--helper.
    That is of course only, when <option> is not a valid option for git submodule foreach.

    The reason for this is, that above call is internally translated into a call to submodule--helper:

    git submodule--helper foreach --recursive \
       -- <subcommand> --<option>
    

    This call starts by executing the subcommand with its option inside the first level submodule and continues by calling the next iteration of the submodule foreach call

    git --super-prefix <submodulepath> submodule--helper \
      foreach --recursive <subcommand> --<option>
    

    inside the first level submodule. Note that the double dash in front of the subcommand is missing.

    This problem starts to arise only recently, as the PARSE_OPT_KEEP_UNKNOWN flag for the argument parsing of git submodule foreach was removed in commit a282f5a.
    Hence, the unknown option is complained about now, as the argument parsing is not properly ended by the double dash.

    This commit fixes the problem by adding the double dash in front of the subcommand during the recursion.


    Note that, before Git 2.29 (Q4 2020), "git submodule update --quiet"(man) did not squelch underlying "rebase" and "pull" commands.

    See commit 3ad0401 (30 Sep 2020) by Theodore Dubois (tbodt).
    (Merged by Junio C Hamano -- gitster -- in commit 300cd14, 05 Oct 2020)

    submodule update: silence underlying merge/rebase with "--quiet"

    Signed-off-by: Theodore Dubois

    Commands such as

    $ git pull --rebase --recurse-submodules --quiet  
    

    produce non-quiet output from the merge or rebase.
    Pass the --quiet option down when invoking "rebase" and "merge".

    Also fix the parsing of git submodule update(man) -v.

    When e84c3cf3 ("git-submodule.sh: accept verbose flag in cmd_update to be non-quiet", 2018-08-14, Git v2.19.0-rc0 -- merge) taught "git submodule update"(man) to take "--quiet", it apparently did not know how ${GIT_QUIET:+--quiet} works, and reviewers seem to have missed that setting the variable to "0", rather than unsetting it, still results in "--quiet" being passed to underlying commands.

    0 讨论(0)
  • 2020-11-27 09:34

    In your project parent directory, run:

    git submodule update --init
    

    Or if you have recursive submodules run:

    git submodule update --init --recursive
    

    Sometimes this still doesn't work, because somehow you have local changes in the local submodule directory while the submodule is being updated.

    Most of the time the local change might not be the one you want to commit. It can happen due to a file deletion in your submodule, etc. If so, do a reset in your local submodule directory and in your project parent directory, run again:

    git submodule update --init --recursive
    
    0 讨论(0)
提交回复
热议问题