GitHubWorkflow

From Mu2eWiki
Revision as of 15:40, 12 March 2020 by Kutschke (talk | contribs)
Jump to navigation Jump to search

Introduction

This page describes a recommended git workflow for use with the Mu2e Offline code in GitHub.

The Mu2e computing group manages the Mu2e organization within GitHub. To have full access to Mu2e software, Mu2e collaborators should create a GitHub account, and request to join the Mu2e organization.

  1. Make sure you have a GitHub account, and that you are added to the Mu2e GitHub organization (https://github.com/orgs/Mu2e/people)
  2. In order to authenticate with github, you will need to set up your ssh keys on the machine you plan to clone / push from, following the instructions here
  3. Before we do any developing, we will create our own fork of the official Mu2e Offline repo using the GitHub web interface (instructions here). This fork will be your personal sandbox on GitHub; you can do anything you want to it and it will have no effect on anyone else!

The main Mu2e repository is 'Offline', which contains the algorithms, data structures, art modules and configuration used in simulation production, online filtering, offline reconstruction, and other tasks. The main development branch within Offline is 'master', which should be used for all code development. Offline also contains legacy branches associated with particular data sets, which are maintained for a limited time after the master branch has been developed past those data, as described in the table below.

Mue2/Offline branches
branch name branch purpose support end date
master development end of Mu2e
MDC2018 MDC2018 dataset support end of 2020

To work on a branch other than master:

> git checkout 'BRANCH' 

where 'BRANCH' is the name of the branch

Authentication

If you are following the instructions for accessing Offline as a user, not a developer, you will never need to authenticate yourself to github. If you will do work as a developer than there will be some steps for which you will need to authenticate yourself to github. The page Authentication#Authenticating to github has instructions on two ways to do so

Migrating an existing redmine clone directory to GitHub

You can repoint an existing Offline clone from redmine to GitHub as a way of making an easy transition. To follow these instructions, you must already have a GitHub account that's registered in the Mu2e Organization. The following assumes your redmine clone is in /mu2e/app/Me/MyRedmineClone/Offline, that your GitHub username is MyGitHubName, and that you are working on a branch called MyDevelopmentBranch.

    1. Login to GitHub
    2. Fork Mu2e/Offline in GitHub using the 'Fork' button on the top right of the Mu2e Offline repo page
    3. Add GitHub as a remote to your clone
      > cd /mu2e/app/Me/MyRedmineClone/Offline
      > git remote rename origin Redmine
      > git remote add mu2e https://github.com/Mu2e/Offline
      > git remote add origin https://github.com/MyGitHubName/Offline
      These commands are very fast as no data is actually transferred. You can see your remotes with:
      > git remote -v
      Your clone is now connected to the main Mu2e github repository and your own fork in addition to the Redmine repository. Additionally, we have changed your fork to be the default remote repository (origin)
    4. Push your working branch to your GitHub fork:
      > git push -u origin MyDevelopmentBranch
    After this, you can continue developing in this directory according to the general GitHub workflow described below.

Downloading Offline as a user and NOT a developer

Option 1: you want the default primary version of the code (most people):

  1. clone the repo:
  2. git clone https://github.com/mu2e/Offline
  3. Done!

Option 2: A particular collaborator has a version or branch you want to use:

  1. Find their github user name
  2. Determine what the name of the branch they are working on is (Note: this can be master!)
  3. Clone their fork:
  4. git clone https://github.com/<user name>/Offline cd Offline git checkout origin/<branch name>
  5. Done!

Option 3: You want to use pgit to avoid a long compilation time (EXPERIMENTAL)

  1. Create new directory to put your Offline repo in and move to that directory
  2. mkdir Offline cd Offline
  3. As in Option 2, determine fork and branch name you wish to use
  4. Create a partial checkout clone
  5. pgit2 setup https://github.com/<user name (or mu2e)>/Offline <branch name>
  6. You can now use as normal:
  7. source setup.sh scons -j 4

Developer Workflow

To start, make sure you understand what a remote is, the difference between a branch and a fork, and what a pull request is.

  1. Create our own fork of the official Mu2e Offline repo using the GitHub web interface (instructions here). This fork will be your personal sandbox on GitHub; you can do anything you want to it and it will have no effect on anyone else! Note that you only need to do this once; you can reuse this fork for all your development projects.
  2. Create a local clone of your Offline fork. This is another step that you only need to do once and you can use this local clone for multiple development projects in you want to. When you push code to another repository, the default will be to push to your fork own instead of the official mu2e version.
  3. git init Offline cd Offline git remote add -f origin git@github.com:<your github username>/Offline git remote add mu2e https://github.com/mu2e/Offline git branch -d -r origin/master git fetch mu2e master
  4. The above steps will create a git repository with the following properties:
    • There are two remotes: your fork and mu2e/Offline
    • All of the branches from your fork, except master, will be visible as remote branches
    • The master branch from mu2e/Offline will be visible as a remote branch.
    • There will be no local branches and no checked out files; so you cannot yet build or run anything.
    • You can inspect the status of remotes and branches using git remote -v and git branch -avv.
  5. When you want to start a new development project, the first step is to make a new local branch on which to do the work. If two development efforts are not intrinsically coupled to each other, each should be done on its own branch. This branch is local to your fork, so has no impact on the main Offline. The branch name is used for sharing your development work with other people while it is still in progress, and for making your pull request, but has no intrinsic meaning.
  6. git fetch mu2e master git checkout --no-track -b <development branch name> mu2e/master
  7. After you have done the previous step, your directory will be populated with files; you can start to edit, build and run. The two commands in the previous step ensure that your new development work starts from the up-to-date head of the master branch in the official mu2e/Offline. Note that the master branch from your own github fork is never a part of this work; in general it will always be very out of date. This is why step 2 is a little complicated: among other things it ensures that the master branch from your fork is not visible in your clone.
  8. Do your work and commit it locally. This makes a local 'backup' of your work.
  9. git commit -m "brief comment describing the changes you are committing"
  10. When your development is complete, or when you wish to back it up remotely, or share your work with others, push your branch back to your GitHub fork. Note this requires you to have setup your github authentication.
  11. git push -u origin <development branch name>
  12. In the previous step the -u option tells git that your local branch should track the branch in your fork. If you push the branch again, the -u option is not needed but it won't hurt if it is present. You can use git branch -avv to see that your development branch is now tracking the version of itself in your github fork.
  13. When your development is complete and tested and ready to be re-integrated with the rest of Mu2e/Offline, go to the GitHub web site and request that your branch be pulled back into Mu2e/Offline. Your pull request will start the code review process, which may take anywhere from a few hours to a few days. Note that GitHub will not allow you to request a pull if your branch conflicts with other development merged since your clone.
    1. In a web browser, open https://github.com/<your user name>/Offline
    2. push the 'new request pull' button associated with your development branch
    3. More info is available at instructions
  14. If your pull request shows conflicts with Mu2e/Offline, you must reconcile those before you can request a pull. This involves first bringing in the latest Mu2e/Offline master branch, and then merging it with your branch. Please do NOT perform these steps if there are no conflicts, as the merging process complicates the git history.
  15. git fetch mu2e master git checkout <development branch name> git merge mu2e/master
  16. if the 'git merge master' step has unresolved conflicts, you will need to edit the code to resolve them. There is no formula for this step; you will have to look at the 2 versions of the conflicting code blocks and decide how to best merge both functionality. If you have questions about the intent of the previously-merged conflicting code, work together with the author of those changes to figure that out. You can figure out who last changed a line in a file using the 'git blame' command.
  17. git blame mu2e/master <name of file that has conflicts>
  18. Once all conflicts from the merge are resolved, commit the merge and push it back to your fork. After this, GitHub will allow you to request a pull.
  19. git add <files that were part of resolving conflicts> git remove <any files that need to be removed to resolve conflicts> git commit -m "Resolve conflicts message" git push origin <development branch name>
  20. If changes are requested during the code review process, make those on the same development branch as your pull request. When the changes are complete, commit them, and push your changes back to your fork. GitHub will automatically add the new commits to the pull request, so the reviewers and the GitHub record will show them.
  21. <edit code as requested by reviewer> git commit -m "Address review comment X" git push origin <development branch name>
  22. When the code reviewers are satisfied, one of the software coordinators will merge the pull into Mu2e/Offline. Once your pull request is merged your changes (commits) will be part of Mu2e/Offline master, and your development branch can be deleted. If you are uncertain if your branch has been merged or not, select the branch, and push the 'compare' button. If this comes back stating there is 'nothing to compare to', it means all your changes were already merged. If it shows differences, those have NOT been merged, so do NOT delete your branch. To delete your branch in GitHub, just push the trash can icon. You can also delete the branch in your shell, as
  23. git branch -d <my branch name> git push origin --delete <my branch name> (this deletes the branch from your github fork as well)
  24. To reuse your working directory for a new development, first refresh to the current head of master, then create a new branch as described above. Do NOT reuse branches for new development, as updating those to the head of Mu2e/Offline master will confuse the git history.
  25. git fetch mu2e master git checkout -b <new development branch name>

Collaborating on a feature

Sometimes you may want to collaborate on a feature branch with other developers. In this case since the main Offline repository no longer has all the development branches we need to do a couple extra steps

  1. First make sure you actually need to work on the same branch. Are you actually working on the same feature? Can the problem be split into smaller features that can be developed asynchronously? Just because features are related doesn't mean they need to be developed on the same branch
  2. Determine if a large number of people will be developing on the same branch for a significant amount of time. In this case it should become an official branch in the mu2e/Offline, like MDC2018
  3. Decide which user's fork will be the primary repo for this feature branch, and which branch on that fork you are going to use. If a new branch is needed, the owner of that fork start the new branch as follows. First make sure that you have done steps 1 and 2 in #Developer_Workflow. Then do the following:
  4. git fetch mu2e master git checkout --no-track -b <branch name> mu2e/master git push -u origin <branch name>
  5. There are then a couple options for moving forward: either add all other developers as collaborators on the primary fork, or use pull requests to the primary fork
  6. To add developers as collaborators:
    1. The owner of the primary fork opens https://github.com/<their user name>/Offline
    2. click settings on the right, then collaborators
    3. In the collaborators box, type the github user name of each other developer and hit "Add collaborator"
    4. The other collaborators can then either create a read/write access clone of the primary fork, or add it as a remote to an existing offline repo
    5. git clone git@github.com:<primary user name>/Offline or git remote add primaryfork git@github.com:<primary user name>/Offline
    6. The other collaborators can now push directly to the primary fork as if it was their own:
    7. git push primaryfork <branch name>
  7. To use pull requests:
    1. The owner of the primary fork can just push to it as normal following the normal developer workflow
    2. Other developers clone their own fork, but add the primary fork as a remote
    3. git remote add primaryfork git@githbub.com:<primary user name>/Offline
    4. Other developers can pull in and merge changes from collaborators by fetching/pulling/merging from this remote
    5. git fetch primaryfork git merge primaryfork/<branch name>
    6. Other developers push to their own fork
    7. git push origin <branch namee>
    8. Like in the normal developer workflow, they open a pull request. But then in the compare window before creating the request, change the "base repository" from mu2e/Offline to <primary user name>/Offline (see here)
    9. the owner of the primary fork will need to accept and merge it in
    10. everything else goes like the normal workflow

I have a branch on Redmine that's not on GitHub! How do I use it now?

The official Mu2e GitHub repo will usually have only the master branch (+ maybe some tagged release branches). Currently Redmine has >100 branches. If you have a Redmine branch that is not merged in to master, you will move this branch to your fork to work on it instead.

To start, you should read the development workflow and understand remotes and forks, and have a github account and a fork of the Mu2e Offline repo.

  1. Create a local clone of your Offline fork. This will be identical to cloning the official mu2e repo (if your fork is up to date), except that the default remote (called "origin") where you will push to by default will point to your fork instead of the official mu2e version.
  2. git clone git@github.com:<your user name>/Offline
  3. Add Redmine as a remote to your local clone:
  4. cd Offline git remote add redmine http://cdcvs.fnal.gov/projects/mu2eofflinesoftwaremu2eoffline/Offline.git
  5. Fetch a list of the commits and branches from redmine, and check out whatever branch you need
  6. git fetch redmine git checkout -b <branch name> redmine/<branch name>
  7. Push this branch to your fork
  8. git push origin <branch name>
  9. You should now be able to see your branch on github.com/<your user name>/Offline. You can now continue working on that branch and pushing to your fork, and when it is ready you can submit a pull request to the main Mu2e repo using the developer workflow