1

I have the following setup, I am working on a project project with the submodule submodule. Whenever I push changes to github it sends a post request to update.php on the server.

This php file executes a git command. Without submodules I can just do a git pull and everything is fine but with submodules it is much more difficult.

I have this at the moment, but it does not do what I want. I should git pull the repo and update and pull the latest version of each submodule.

<?php echo `git submodule foreach 'git checkout master; git pull; 
git submodule update --init --recursive; git commit -m "updating"' && git pull && 
git submodule foreach 'git add -A .' 
&& git commit -m "updating to latest version including submodules" 2>&1s`;

EDIT// Okay, I got it half way done.

<?php echo `git submodule foreach 'git checkout master; git pull; 
git submodule update --init --recursive; git commit -am "updating"; echo "updated"' && 
git pull &&  git commit -am "updating to latest version including submodules" && 
echo 'updated'`;

The echo prevents the script to stop because of non-zero returned. It works 100% fine when I run it from the console using php update.php.

When github initialized the file, or I run it from the browser it still does not work.

Any ideas?

Lukas Oppermann
  • 2,918
  • 6
  • 47
  • 62
  • What does it instead? Have you tried switching the `git pull` and the first `git submodule foreach …`? The second `git submodule foreach …` has no `git commit`. – Michael Oct 02 '12 at 15:51
  • I tried it all, and since it works fine running it from the console it should actually not be a problem in the script right? Could it have to do with permissions? If so, how can I fix it? – Lukas Oppermann Oct 06 '12 at 05:15
  • You said „Without submodules (…) everything is fine”, so I guess the webserver has the required permissions. What about the scripts running time? Where does it stop? – Michael Oct 07 '12 at 20:26
  • Btw., why do you want the server to update the submodule? Are you sure the project works fine with the latest version of the submodule? After all, you only tested it with the last checked-out version. – Michael Oct 07 '12 at 20:30
  • Yeah, I will make it optional to update submodules, but if I push a new submodule version, the server still runs the old version, if it only pulls the main repository from git, right? – Lukas Oppermann Oct 07 '12 at 23:10
  • 1
    Right. `git pull && git submodule update --init --recursive` lets the server check out the referenced commit of each submodule in the latest commit of the main repo. – Michael Oct 07 '12 at 23:21

1 Answers1

2

Even if it would work there are things you should know about:

  1. If there are new submodules, you don't init them. So you should start your script with git pull && git submodule update --init.

  2. git commit -am "updating" doesn't create a new commit because you didn't change anything in the submodule.

    • git checkout master only checks out branch master. This makes sense because of the otherwise detached head.

      Note: There might be repos where master is not the branch you want! See note below.

    • git pull fetches from the remote and merges the changes into master. Even if this is not a fast-forward merge¹, there's nothing to commit as the merge commit is made automatically.

      ¹Because this is a checkout on your server there shouldn't be a need for a non fast-forward merge. Otherwise you should think about merge conflicts and git push (see 3.), too!

    • git submodule update --init --recursive only fetches from the submodule's submodule remotes and checks out the already referenced commits. So nothing new to commit here, either.

  3. If git commit -am "updating" would actually create a commit, the commit would be only available in the checked out version (fork), not in the referenced repository (see url = … in .gitmodules). So you commit references to submodule commit hashs in git commit -am "updating to latest version including submodules" that do not exist anywhere else.

    So in this case you would need to add a git push to your git submodule foreach '…'. See also here.

  4. As I mentioned in a comment to your question this workflow has one major disadvantage: Nobody tested the project files with the latest commits in the submodules. This might break the project!

Try (indented for better readability):

<?php echo `git pull &&
  git submodule update --init &&
  git submodule foreach 'git checkout master;
    git pull; 
    git submodule update --init --recursive;
    echo "updated"' && 
  git commit -am "updated submodules" && 
  echo 'updated'`;
?>

Note on permissions:

You said it works (with submodules) when using the php cli. Did you try this on your local machine or on the server? And if you did so on the server did you try it using the webserver's account?

Note on submodule branches:

Using git checkout master (see 2.1) lets you only use the master branch of a submodule. To change this add update = rebase or update = merge to each entry in .gitmodules. (No detached head any more!) Then run git submodule foreach 'git checkout master' (or check out/create any other tracking branch) and you can simply use git submodule foreach 'git pull' from now on.

Community
  • 1
  • 1
Michael
  • 1,502
  • 19
  • 29
  • Perfect, I just made it to complicated thanks to your tip with the rebase I just use `git submodule foreach git pull` for including the changes in my repo and on the server run a simple `echo git pull && git submodule update --init --recursive 2>&1;` and it all works. Thanks. – Lukas Oppermann Oct 08 '12 at 02:26