What is the git procedure/workflow for updating a fork with modified submodules?

Hi,

I’ve got limited experience working with git and this project is my first exposure to submodules and I’ve run into a few problems dealing with them in the past such as this: http://discuss.ardupilot.org/t/handling-submodule-updates/8692. I’ve made a fork of ardupilot and cloned that. I’ve made changes to some of the code in addition to changes in /modules/mavlink/. I Can’t commit the changes in mavlink as I don’t have write access to the repo so I’ve left those changes (perhaps niavely) untracked.

This leaves me in a state whereby if I want to work on another computer I can:

git clone https://github.com/<my_username>/ardupilot.git
git submodule update --init --recursive

and then change the /module/mavlink/ message definitions file as I need manually. Inelegant, but it usually works.

I’ve merged ardupilot upstream changes in the past but just recently I tried to merge but had conflicts for the submodules directories, not in any files. I did my best to try resolve them but couldn’t get the build to work (it relies on git submodules). It’s worth noting that I tried merging instead of rebasing, and I’m not entirely sure on which is the best to use. I noticed that Tridge recently made commits after updating submodules, so maybe that’s the difference this time around (there were conflicts with other submodules I’d never changed).

I’ve sinced reverted to the previous state I had by deleting the ardupilot folder and cloning the last pushes I’d made to github. I’m now in a state where I can make changes and build the code but can’t merge changes from upstream.

Can someone please suggest the workflow/git commands that must be used when dealing with modified submodules, and keeping them, and ardupilot up to date by regular merges?

As far as I’m aware, the best way would be to have a fork for ardupilot AND a fork for ardupilot/mavlink and have my ardupilot/.gitmodules “point” to https://github.com/<my_username>/mavlink.git instead of the read-only git://github.com/Ardupilot/mavlink url. I should then implement changes, commit, merge(rebase), push within the repos independently.

Say I was to do this the right way from scratch, should I do the following?:

On github.com:

fork ArduPilot/ardupilot to <my_username>/ardupilot
fork ArduPilot/mavlink to <my_username>/mavlink

On my local computer:

git clone https://github.com/<my_username>/mavlink.git
cd mavlink/
git submodule update --init --recursive

*Change mavlink message definitions as needed*

git add -A
git commit -m "<message>"
git push
cd ..
git clone https://github.com/<my_username>/ardupilot.git

*Change .gitmodules mavlink path to use url: https://github.com/<my_username>/mavlink.git*
*Make changes to ardupilot that I require*

git submodule update --init --recursive

(Will this break because I’ve already done init within my own mavlink fork?)

*Check I can build the code correctly and my changes work*

git add -A
git commit -m "<message>"
git push

I should now have a working repository, but say I want to keep mavlink up to date and keep ardupilot up to date with the upstreams:

Create upstream remotes:

git remote add upstream https://github.com/ArduPilot/ardupilot.git
cd mavlink/
git remote add upstream https://github.com/ArduPilot/mavlink.git

Later on merge some changes from upstream, in mavlink say:

git checkout master
git fetch upstream
git merge upstream/master

*Resolve conflicts (probably none in mavlink)*
git push origin/master

Now I’m expecting that ardupilot will have some untracked changes in the mavlink submodule so:

cd ..
git add /modules/mavlink
git commit -m "Updated mavlink module."
git push

Now If I wanted to merge changes in the ardupilot repo (more important):

git checkout master
git fetch upstream
git merge upstream/master

Resolve conflicts

git push origin/master

Would this work? I’m worried that there would be conflicts between upstream modules/mavlink and my local modules/mavlink.

Instead of updating and merging the modules independently as described above, would simply

git submodule update --merge --recursive

achieve the effect of merging changes in upstreams for ardupilot and mavlink without clobbering my local build?

I’ve probably missed a few things so let me know if you need more info. I want to have the repo and submodules set up correctly from the start so we can merge in changes to ardupilot as it develops and not be stuck with an orphaned project years from now.

Regards,
Mike Shanaher

You can easily add you own repos to each submodule as you modify them. You need to for the repo in github so you have your own fork. cd to the module and then rename the origin which is pointing to original repo to be upstream. the you can add your repo as origin. (note the example below is for mavlink module, but you would do the same for each module dependency you wanted to work on)

$ cd ardupilot/modules/mavlink
$ git remote rename origin upstream
$ git remote add origin https://github.com/<my_username>/ardupilot.git
$ git checkout master (or git checkout -b my_modfied_branch to create you modified branch ready for a PR)

then to push you use the git push origin <branch_name> to save in your own repo in github

Do the same of a clone on another machine, you can then go to the module dir and pull down, and push up your changes to your local repo