-
Notifications
You must be signed in to change notification settings - Fork 22
Working on a PyFerret branch other than master
Example demonstrating using the dsg branch of the PyFerret GitHub repository for development. Although much of this is identical to using the dsg branch of the Ferret GitHub repository, there is additional capability to merge changes in from the dsg branch of the Ferret GitHub repository.
Clone the PyFerret GitHub repository to some local directory (in this case ~/git/pyferret_dsg
)
specifying the branch you want to work in (in this case, dsg
):
<~/git> % git clone --branch dsg [email protected]:NOAA-PMEL/PyFerret.git pyferret_dsg
This clones the repository as usual, but instead of checking out the master branch, it checks out
the specified branch. The only local branch will be the specified branch (dsg
), although
the other remote branches are known.
<~/git> % cd pyferret_dsg
<~/git/pyferret_dsg> % git branch
* dsg
<~/git/pyferret_dsg> % git branch -a
* dsg
remotes/origin/HEAD -> origin/master
remotes/origin/aggaxes
remotes/origin/dsg
remotes/origin/master
One can checkout and switch (in place) between any of the branches in a clone of the repository. So one could have a single clone of the GitHub PyFerret repository and use that for all branches, which is probably more typical for GitHub users. But (at this time) I prefer keeping separate clones (more like subversion) to ensure I do not get things mixed up; such as thinking I am working on the dsg branch and then realize I am still using the master branch - hopefully before I have committed anything.
Because PyFerret is actually a branch off of Ferret, one can specify the GitHub Ferret repository as an "upstream" repository, which allows merging in changes made in Ferret code into PyFerret code.
git remote add upstream [email protected]:NOAA-PMEL/Ferret.git
This command only adds the name upstream
as a known remote site;
nothing is uploaded at this time.
<~/git/pyferret_dsg> % git config --list
...
[email protected]:NOAA-PMEL/PyFerret.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.dsg.remote=origin
branch.dsg.merge=refs/heads/dsg
[email protected]:NOAA-PMEL/Ferret.git
remote.upstream.fetch=+refs/heads/*:refs/remotes/upstream/*
From this point, work as usual: edit your files, git add
, git commit
, git push
.
When you execute git push
(without any other arguments), it will by default push to the
corresponding branch in the remote repository (and the branches must have the same base name;
e.g., dsg
and remotes/origin/dsg
).
Then you execute git pull
, it updates all information about the repository (so it might
show updates from the master of other branches), but only changes applicable to your branch
will be seen and you will still be in your branch.
If you wish to incorporate new changes in the master branch into your branch, first
<~/git/pyferret_dsg> % git pull
to update your local repository so it knows about any changes in the master branch, then
<~/git/pyferret_dsg> % git merge origin/master
<~/git/pyferret_dsg> % git push
to merge in the changes in the master branch into your current (dsg) branch.
If there are any incompatibilities, you will need to resolve those issues and commit the changes.
If there the merge went cleanly, it will automatically go to the commit (add --no-commit
if you want look at the results on the merge before committing them).
Periodically merging from master will reduce the amount of work required when you are done with
your changes and want to merge your branch back into master.
(You will have to merge the master branch into your branch, just to be sure you have all the
latest changes, before you can merge your branch back into the master branch.)
A similar operation is used to merge in changes made in the Ferret repository.
First retrieve any changes made in the Ferret repository using the fetch
subcommand:
<~/git/pyferret_dsg> % git fetch upstream
then merge in the Ferret dsg branch:
<~/git/pyferret_dsg> % git merge --no-commit upstream/dsg
... (resolve any issues; inspect the code)
<~/git/pyferret_dsg> % git commit
<~/git/pyferret_dsg> % git push
If you have merged the Ferret master branch into the Ferret dsg branch (and pushed out those commits), then a merge the Ferret dsg branch into the PyFerret dsg branch also records the merge of the Ferret master branch. Similarly, if you have merged the Ferret master branch into the PyFerret master branch (and pushed out those commits), then a merge of the PyFerret master branch into the PyFerret dsg branch also records the merge of the Ferret master branch.
Most often these merges will occur without incident, but there are some portions of
PyFerret code where conflicts will arise (due to code divergence) and need to be resolved.
On very rare occasions the merge will happen without incident, but examination of the
changes show something was not done quite right.
Often it is just duplication of a change, which probably is the result of the merge
having previously been done through subversion and then pushed out to GitHub using
git svn
, but was not detected as the same change in the git merge
.
For this reason, adding the --no-commit
flag in these merges is recommended
so you can verify the changes before committing them.
To propagate changes made the Ferret master branch, I usually first merge those changes into both the PyFerret master branch, resolving Ferret-PyFerret issues from code divergence, and the other (dsg) Ferret branch, which is likely to proceed smoothly. I then merge the PyFerret master branch into the other (dsg) PyFerret branch, which is likely to proceed smoothly and incorporates the Ferret master branch along with the resolution of any code divergence issues. Finally, I then merge the other (dsg) Ferret branch (if there were any changes specific to that branch) which is more likely to proceed smoothly only changes specific to the Ferret dsg branch are being incorporated.
<~/> % cd ~/git/ferret_dsg
<~/git/ferret_dsg> % git pull
<~/git/ferret_dsg> % git merge origin/master
<~/git/ferret_dsg> % git push
<~/> % cd ~/git/pyferret
<~/git/pyferret> % git fetch upstream
<~/git/pyferret> % git merge --no-commit upstream/master
... (resolve Ferret-PyFerret code divergence issues)
<~/git/pyferret> % git commit
<~/git/pyferret> % git push
<~/> % cd ~/git/pyferret_dsg
<~/git/pyferret_dsg> % git pull
<~/git/pyferret_dsg> % git merge origin/master
(above resolution of code divergence issues incorporated)
<~/git/pyferret_dsg> % git fetch upstream
<~/git/pyferret_dsg> % git merge --no-commit upstream/dsg
... (only dsg changes left to be merged in, so less likely to have issues to resolve)
<~/git/pyferret_dsg> % git commit
<~/git/pyferret_dsg> % git push