Git commit to common submodule (master branch)

前端 未结 6 1599
南方客
南方客 2020-12-02 04:56

I\'ve two or more projects (let\'s call them ProjectFoo and ProjectBar) having some common code that I put in a submodule

相关标签:
6条回答
  • 2020-12-02 05:29

    Short answer:

    cd ProjectFooBarCommoneSubmodule
    git checkout master
    <Do your editing>
    git commit --all -m "Lots of fixes"
    git push submodule_origin master
    cd ..
    
    git add ProjectFooBarCommoneSubmodule
    git commit -m "Bumped up the revision of ProjectFooBarCommoneSubmodule"
    git push origin master
    

    The longer one:

    Git submodules are a dependency mechanism, where the main project (say A) defines a specified revision in a subproject (say B), which will be used in building project A. In order for the tool to be useful the behavior has to be predictable from A:s point of view. Dependencies cannot change, unless somebody decides to incorporate the change to project A. All kinds of nasty things could happen, were project B:s changes automatically imported, of which compile errors are probably the best ones, as A would notice the failures immediately. This is why B:s head is kept in detached state.

    The state of B is store in A (check out git submodule status), and a revision change has to be done and committed in A, in order for it to have any effect. This is what happens in the example above, A changes the revision number stored in the repo, and bumps up the version to the latest one. The process will have to be repeated in the other main repo as well, so no automatic "use master" switch AFAIK.

    BTW. The Git book chapter on submodules and the submodule man page contain lots of useful info about submodules, as normal usage and typical pitfalls as well. Worth checking out.


    EDIT: I'll try to explain this better

    I took the liberty to create example projects on my github account. The commits are meaningless and contain junk, but the setup should be fine. Please check it out to follow.

    Both ProjectFoo and ProjectBar share the code in the common submodule.

    ProjectFooBarCommoneSubmodule:master is 6850e4e4c1fac49de398

    In ProjectFoo:

    git submodule status
    

    -6850e4e4c1fac49de39890703f21486ca04b87a0 common

    In ProjectBar:

    git submodule status
    

    -6850e4e4c1fac49de39890703f21486ca04b87a0 common

    So both point to the same revision, right? The trick here is to see, that ProjectFoo and ProjectBar point to the revision (6850e4e4c1fac49de39890703f21486ca04b87a0) not the branch (master), although they are the same thing. The first one is a detached head, and the other a named branch.

    If you want to do some fixing on ProjectFooBarCommoneSubmodule, you can go to the subdir in e.g. ProjectFoo, and choose the branch instead of the revision:

    git checkout master 
    <Do your coding and pushing here>
    

    Then go one directory up, and check git submodule status. It should tell you, that you are now out of sync. E.g

    git submodule status
    

    +e24bd2bf45d52171a63b67ac05cd4be0ac965f60 common (heads/master-1-ge24bd2b)

    Now you can do a git add, to set the reference to this particular commit(ge24bd...), do a commit, and after this the submodule reference points to this revision, which also happens to be master on ProjectFooBarCommoneSubmodule.

    Now you need to update the reference in ProjectBar as well. Go to ProjectBar/common, and do git fetch origin (this is a fast forward merge), do

    git checkout master 
    cd ..
    git add common
    git commit -m "Bumped up the revision"
    git push origin master # to publish the revision bump to everybody else
    

    So, as with any git repository, you don't need to work on a detached head. You can either work on master, or create a named branch. Either way, make sure that upstream contains the ProjectFooBarCommoneSubmodule changes, or you will break both ProjectFoo and ProjectBar, if they reference something that doesn't exist. Hope this explained it better

    0 讨论(0)
  • 2020-12-02 05:33

    I just do:

    git submodule foreach git push -u origin master

    0 讨论(0)
  • 2020-12-02 05:33

    If you want to commit and push all submodules at once do:

    git submodule foreach 'git commit -a' ;
    git submodule foreach 'git push --all' ;
    git commit -a && \
    git push --all --recurse-submodules=on-demand
    
    0 讨论(0)
  • 2020-12-02 05:35

    To merge changed from detached HEAD into master, run:

    git rebase HEAD master
    

    then checkout master (use -f for force):

    git checkout master
    

    If you've got multiple submodules to deal with, use: git submodule foreach, e.g.

    git submodule foreach git pull origin master -r
    
    0 讨论(0)
  • 2020-12-02 05:46

    On the submodule: git push origin HEAD:master

    0 讨论(0)
  • 2020-12-02 05:53

    Notice:

    git submodule foreach 'git commit -a'
    

    will fail if one of the submodules containt no commit to do.

    To get rid of this, you have to force the command result to 0.

    git submodule foreach "git commit -am 'your comment' || echo ' '"
    

    By using the echo piped you force the whole command to return with 0 and continue executing the commit command on the other submodules

    0 讨论(0)
提交回复
热议问题