Development Reference
This document provides details on E3SM development conventions and practices.
Introduction
All E3SM developers should consider themselves stewards of the repository history. Our goal with defining a workflow is to improve the utility of the repository and create a useful history that can provide a tangible benefit to other developers.
As always, it’s a good idea to understand what you’re doing before you do it. This document should not take the place of understanding, but can be used to learn and remember.
How to use this document
This document expands on portions of the Development Getting Started Guide providing more detail on E3SM development workflow. You should read the Quick Guide first, and use this document as needed.
Specific pieces of information will be colored as follows:
important -- Items colored in red mean they are important, and should not be ignored.
one time -- Items colored in green are commands to be issued once per machine.
repo once -- Items colored in orange are commands to be issued once per local repository.
common -- Items colored in bold black are commands that will be commonly used.
Project Life Cycle
Before getting into the git commands related to our workflow, here is an overview of the life cycle of a feature. This can be used to get a big picture that will be broken up in the following steps.
In the above image, red dots represent merge commits of features into an integration branch. Orange dots represent commits a developer makes as part of a feature branch. Blue commits represent merge commits incorporating a completed feature into the master branch. Purple commits represent tagged versions of the full model.
NOTE:
Within this diagram, blue dots have associated feature branches that are omitted for the sake of readability. However, each of them followed the same development cycle as the feature that is being focused on in the diagram. Also, red commits are made to next. Both next and master should only be modified by integrators or gatekeepers.
Basic Development
Creating a new branch-new feature
New development should be carried out on a branch. New developments include the addition of a new feature (github-username/component/feature) or fixing a bug (github-username/component/bug-fix).
Your branch will typically start from master. It may start from another developers branch or a maintenance branch. Never start a branch from "next".
When creating a branch, please name it based on guidelines contained in Branch, Tag, and Version name conventions. You should also create a set of baselines for tests you plan to use to verify your code changes, and store these baselines in a location specific to your new branch. This procedure is described in Testing.
NOTE:
As seen above, E3SM utilizes a naming convention for branches. Branches have compound names separated by a “/” to describe what large scale part of E3SM the branch changes will modify. The / does not denote a directory, it just is used in naming the branch. This lets other developers know what these branches are developing and what parts of the model they should be modifying. This practice will be referred to as “namespacing a branch”
When creating a branch, multiple levels of namespacing are allowed. In E3SM, a branch should always be namespaced first by github user in charge of the branch. Next comes the main component the feature is being developed for. Finally, a description of the new development. For example, a branch that is implementing a new parameterization within EAM would be named:
joeuser/eam/new-parameterization
And a branch that is modifying the HOMME dynamics would be:
janeuser/homme/new-se-feature
Branch names should be as long as needed to clearly convey what the developer is working on, but they shouldn’t be overly long and descriptive. The following example is a branch name that is too long:
joeuser/cam/this-is-my-awesome-new-feature-that-does-something-cool-and-we-might-not-use-in-the-future
The following diagram depicts two branches that are created. One to fix a bug (github-usernam/component/bug-fix) and another to master a new feature (github-username/component/feature).
The following commands can be used to create the feature branches:
git branch github-username/component/feature
The above command assumes you are on the head of the master branch and that is where you want to start the new development.
If you want to start development from a specific tag, include the tag name as an additional argument.
git branch github-username/component/feature v1.0
When creating a new feature branch, best practice suggests you should branch from a tested version of the code. HOWEVER, while the model is in "version 0" mode, always start development from the HEAD of master.
Creating a new branch-bug fix
Typically, a bug fix is applied to the commit that introduced the bug. In that case, the branch creation has an additional argument:
git branch github-username/component/bug-fix commit-with-bug
The last argument is the hash of the commit that first introduced the bug. If that was a tagged version, you can use the tag name as for the feature branch above.
It is ok to fix multiple bugs on a single bug fix branch if it makes sense to do so (e.g. one related set of code changes can fix multiple bugs.)
In order to find the hash of the commit that introduced the bug, a developer can use:
git blame file-with-bug
This will open the file with the bug in a text editor, and annotate each line with the commit that last touched it. This can be traced back to find the commit that introduced the bug.
EXCEPTIONS: You can start a bug-fix branch from the HEAD of master if any of the following are true:
- The bug existed in code imported from CESM such as in the initial version added to the repo.
- The bug was introduced prior to v0.3 (the version where the testing is working)
Creating a new branch-on a maintenance branch
The E3SM repository will have one or more active maintenance branches usually to keep adding bug fixes and machine updates to old versions. See E3SM permanent branches for the list of maintenance branches, their purpose and what kind of changes they will accept.
If the feature, machine update or bug fix you are working on needs to go on a maintenance branch, switch to that branch before making your feature branch. For example:
git checkout maint-1.0
This will put your working directory at the head of the maintenance branch. You can then start a new branch as you do for master. When you make a pull request, specify the maintenance branch as the "base".
If you need to fix a bug on a maintenance branch and the bug was introduced by a commit on the branch, you can follow the same directions as for a bug-fix branch.
If you are developing something for both a maintenance branch AND master, do the maintenance development first. You can then ask the integrator to merge maint to master. Or you can make 2 pull requests, one for maint and one for master.
If your development depends on something that was added to master AFTER the maintenance branch started, it can not be added to the maintenance branch. Master "contains" the content on the maintenance branches (if they are not too old) and one can merge from maint to master. We can not merge from master to maint.
IMPORTANT: We do not have "next" branches for maintenance branches to test multiple features against each other. To compensate, all development on a maintenance branch should be done sequentially. That is, one developer makes their branch, completes the feature, tests it and then has it integrated to the branch before the next development starts. This should not be a problem because maintenance branches are not supposed to have heavy development. You should always test feature branches but this is more important for maintenance features since there is no "next" testing and you don't want to break the maintenance branch by integrating a broken feature.
Changing Branches
Creating a new branch will not change the current branch that is being worked on in the current working directory.
Because the git branch command does not modify the current branch in the current working directory, new commits will not be made to the new branch. In order to change the branch that is being worked on, the git checkout command is used. For example:
git checkout github-username/component/feature
will change the current branch to be github-username/component/feature.
NOTE:
Creating a new branch and swapping to it can be done in a single command via:
git checkout -b github-username/component/feature master
Committing new files and changes as you go
While working on a feature or a bug fix, you will be editing source code files. After editing a file, you might want to commit those changes to your local repository in order to checkpoint your work. When you make a change that you want to commit you "add" it to the git stage with this command:
git add path/to/file/in/repo
The next commit that is created will contain all changes in the stage by default. If you create a new file, also use git add to make the repo aware of it.
A commit can have changes from multiple files. In order to commit only the changes in the staging area, the following command can be used:
git commit
NOTE: The git add command will only stage the changes in the file at the time you issue the command. If the file is subsequently modified you need to run git add again if you want those changes to be committed. Use git status frequently to see the status of staged and un-staged files.
git commit will open up an editor where a commit message can be written. Please refer to the Commit and PR message template for more instructions on the E3SM commit message guidelines.
It is tempting to do development with lots of little commits like this:
f8ef2b5f75 fix
d2e3616d55 progress
e58c74745f more progress
0be335ead0 almost working
If you make "checkpoint" commits like this, be prepared to rewrite the commit history using "git rebase" (See https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) so that each commit has a substantive message as required in Commit and PR message template. See
Utilizing the repository history
Seeing as all of the E3SM developers are stewards of the repository history, it would be useful for developers to understand how to make use of the history they are maintaining.
The most useful command for making use of the history is the git log command. This command has an abundance of optional arguments and this second can be used to get an idea of what you can do with git log.
The basic usage of this command gives the equivalent of an svn log. Where you get a list of all commits and their commit messages. By default, git log only shows commits that are reachable in the history of the HEAD. Optional arguments can be used to look at different (or all) branches.
One extremely useful version of git log gives a command line graph of the history.
git log --oneline --graph --decorate
git log can also only show local branches that match a certain naming convention. i.e.
git log --branches=*pattern*
The --branches option can be replaced with --remotes to only show remote tracking branches that match a pattern.
A specific commit has three pieces of information. The first is the commit’s tree (i.e. the files and directories contained in the commit), the second is the commit’s message (the commit message issued when creating the commit), and the third is a list of the commit’s parents. There can be multiple parents for a single commit, which would imply the commit was a merge commit. Git stores the order of the parents, with the first parent always being the commit the merge was initiated from. This is useful to note, because within our workflow first parent commits on master should always be merge commits bringing in features or bug fixes. git log can be used to narrow your view to only see first parent commits as well, via:
git log --first-parent
As you develop a new feature, you might migrate files from one place to another, or even rename the file. In order to have git show you all renames of a file, you can use the following command:
git log --name-only --follow -- path/to/file
Any of these options can be combined to give more flexibility to exploring the history of a git repository and make the history more useful.
Advanced: Incorporating another branch on to your branch.
When developing a new feature, another developer might have created a feature you require for your work, or another developer might have made large changes to the interfaces you make use of. This section will describe how to incorporate those changes into your branch.
NOTE:
This action can have negative consequences and cause issues in the future, so it is important to know what you’re doing prior to doing any of these.
Cherry-pick method
The first option for incorporating changes from another development line into your development history is via a cherry-pick. A cherry-pick will copy individual commits (or a range of commits) from one point in history onto the HEAD of your current development line. It should be used when the number of commits your future development efforts depend on are small (order 1-10). It can be used as follows:
git cherry-pick <commit-ish>
This method is the easiest to use and one of the least likely to create issues in future development, and allows the most flexible review modifications. One downside to this method, however, is that the commits that are cherry-picked will now occur twice in the history.
Merge Method
The second option for incorporating changes into your development history is via a merge. A merge will attempt to merge an arbitrary number of other commits (or branches) into your current branch. It can be used as follows:
git merge [commit-ish1] [commit-is2] …
In this case, you can list how ever many commits you want on this line, and git will attempt to merge them all into the commit you are currently working on (into your working directory).
The merge will allow you to enter a commit message. The commit message should be very descriptive. It should explain what you’re merging, and why you’re merging it.
NOTE:
A merge creates a fixed point in history. The merge commit fixes all history before it, which limits possibilities for cleaning up history during a code review. A merge should be avoided if at all possible, but in some cases it is necessary. If it is necessary, try to clean up all history prior to the merge before beginning the merge.
Rebase Method
The third and final option for incorporating changes into your development history is via a rebase. A rebase allows you to modify commits. This includes operation such as squashing, re-ordering, deleting, etc. When you create a branch, the base of the branch is the commit you branched off of. A rebase allows you to modify what the base of your branch is. The following diagram can be used to visualize a rebase:
When performing a rebase, you specify the new base for your work. Rebase will then replay your work onto the new base. For example:
git rebase -i new-base
Will replay the history from the current branch on top of the new-base. The -i flag in this case allows interactive modification of the commits to replay. It should be used to verify what is going to happen after the rebase.
NOTE:
Commits that occur prior to a merge cannot be modified, or rebased. In general, if you previously merged within your branch (i.e. to incorporate an “external feature”) or if your branch was previously merged into another branch, you should not rebase anymore, because it will cause conflicts during future work.
Finishing Up
Submitting a pull request (PR)
Once you think development is finished on your branch, you should push the branch to the shared repository (if you haven't already), and submit a pull request (PR) for the integration of your feature into master.
A pull request initiates a process to merge your branch into master. The process will be documented with the subsequent code review via discussion and comments on the PR.
- Commit all your changes locally.
- Clean up any "checkpoint" commits. After development is done, may have commits that look like:
f8ef2b5f75 fix
We do NOT want these in our commit history. Use git rebase (see https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) to rewrite the history of your branch and group these in to substantive commits that follow our Commit and PR message template
d2e3616d55 progress
e58c74745f more progress
0be335ead0 almost working - Push the cleaned-up branch to the github repo.
- go to https://github.com/E3SM-Project/E3SM/branches and find your branch. Click on "New pull request".
- You should verify base and compare of your pull request are correct. The "base" is master and "compare" is your branch.
- When updating submodules:
- submit a PR to submodule's repo first: e.g. a PR to https://github.com/E3SM-Project/kokkos
- if you can't submit a PR, request "push" access from the developers of the submodule
- after the PR is merged, submit a PR to https://github.com/E3SM-Project/E3SM updating submodule hash
- submit a PR to submodule's repo first: e.g. a PR to https://github.com/E3SM-Project/kokkos
- When updating submodules:
- Enter a PR Title: Make sure the title is 70 characters or less and explains the PR in a "verb noun" format like "add cool new feature". Do not just use the branch name or what is filled in by default. (If your branch has a single commit, the title of that commit will be the default, but if your branch has multiple commits, the branch name will be the default.) You should edit the title to make sure it is descriptive enough. DO NOT include github issue #'s or JIRA tasks in the title. Hyperlinking does not work from the title.
- Write a PR Description.
- In the "Write" field, provide a descriptive message of what all the commits in the PR will do together. This description will be used as the commit message when the branch is merged so follow the Commit and PR message template guidelines.
- If a bug fix: after the description, close any Github issue numbers for the bugs this commit fixes using keywords like "Fixes #123". See https://help.github.com/articles/closing-issues-using-keywords/
- After the description and any issue numbers, add a keyword indicating how the PR might change answers.
- [BFB] or [non-BFB] or [CC]: Add ONE of these keys to indicate if this commit will affect testing results to roundoff [non-BFB] or climate changing [CC]. Use [BFB] if-and-only-f commit is bit-for-bit and you know all the tests will pass without regenerating baselines.
- [FCC]: Add [FCC] if the commit will change climate if a flag is activated
- [NML]: Add [NML] if the commit introduces changes to the namelist.
- The reviewer will review the description as part of the pull request. The description will be used in the commit message used when the PR is merged to next and master. The integrator may work with you to edit the PR description. Do not include Confluence URL's in the PR description.
- Give PR label(s) ('Label' pull down menu). Add a label for the component this PR involves. Add the "bug fix" label if this is a bug fix. Add the label(s) for BFB, non-BFB, CC, FCC, NML as appropriate.
- Assign a single Integrator to manage the PR ( use the 'Assignee' pull down menu).
- If you want additional reviewers, add them using the Reviewer pull-down menu. Anyone can be asked to review.
- When complete, click on "Create pull request". This will start the code review and the process of moving this feature to master.
- After pull request is created, add the following in the Comments section:
- In the first comment, provide a link to the Design Document governing this PR. See /wiki/spaces/CNCL/pages/25231511.
- In subsequent comments.
- Provide information to aid the Integrator in running, testing, and validating the feature (but that is too specific to be included in the general PR description).
- Say how the feature was tested. Example: "e3sm_developer on Titan passed". If a test is expected to fail and required redoing baselines, state that and list the tests that fail.
Your PR is not finished until it has been merged to master by the Integrator.
This document can be used to help with pull request related issues.
Integrator Code Review (Phase 3 of /wiki/spaces/CNCL/pages/25231511)
Issuing a PR and review by an integrator is done in Phase 3 of ACME's /wiki/spaces/CNCL/pages/25231511.
Phase 3 code reviews are conducted online on GitHub using comments on the pull request.
Integrator code review steps
- Check the github entry for the PR and make sure it has a good title and description, correct labels and a comment with a link to the Design Document. A PR can not be merged to next or master unless it has a Design Document with Phase 1 and 2 completed. See /wiki/spaces/CNCL/pages/25231511.
- Look at the code changes either on github or using: git log --reverse -p master.. on your checked out copy of the branch.
- Does new code hold up to visual inspection for code quality? Look over code changes for glaring mistakes or code style issues (e.g. useful comments, reasonable subroutine lengths, new code in an existing file follows conventions of that file).
- Check to see if the description of the code changes in the PR match the actual changes. Make sure nothing unrelated to the PR was committed accidentally.
- Although they can't be changed, see if commit messages on the branch follow the Commit and PR message template and let the developer know if they can not. Consider asking the developer to squash commits to clean up the history.
- Have tests been added or suggested that exercise this feature?
- Does code run on all platforms after integration into next?
If there are any problems, work with the developer to correct them. All correspondence should be done as comments to the PR in github.
An E3SM group may define additional review procedures for code changes affecting their component.
Handling reviewer comments
During a code review there are several steps. The first step is for a reviewer to review your pull request description, along with the code and commits from the pull request. The reviewer is allowed to request the following from a developer:
Modify the pull request description
Modify commit history (Including removal, reordering, squashing, etc)
Modify code. This could be requested for stylistic reasons, or functional reasons.
Modifying the pull request description is as simple as editing the wording of the pull request description via github’s website.
Modifying the commit history requires rebasing. In this case, you want to figure out what the base of your current branch is. It is likely that you branched off of master, in which case you can use the merge-base command to determine your base. For example:
git merge-base github-username/component/my-feature origin/master
will tell you the commit that is the base of your branch. If you perform an interactive rebase onto the merge base, you can modify the history of your branch without introducing merge conflicts associated with changing your base. For example:
git rebase -i $(git merge-base HEAD origin/master)
will rebase your branch using the tip of the E3SM master branch as its base. Finally, modifying code might require introducing new commits, or editing previous commits.
Editing existing commits
Occasionally, you may need to change one of the commits you've made. For example, if you added a file that shouldn't have been added to the repository, you may want to eliminate it from the commit to prevent it from being tracked in the repository's history.
There are several ways to edit an existing commit. In general, the commands you use are case specific, so general commands cannot be provided. Instead, general command usage and guidelines will be provided, but the integrator helping with the pull request should be able to give more information about specific commands.
One way to edit existing commits is to interactively rebase a branch onto it's own base, which is found using the merge-base command in the above section. After typing the rebase command, a text editor will open with several lines. Each line represents a commit that git will allow modification for. The lines can be broken down into the following information:
action hash subject
The hash and subject provide information about each commit so you know which is which. The listed on each line is an abbreviated hash prior to the rebase. The subject is the first line from the commit message for that commit. On each line, action tells git what it should attempt to do with the specific commit. Available actions depend on your git version, but all of them start with a default value of pick. Pick means git will "cherry-pick" the commit and leave it as is. In this case, we want to change pick to edit on the commit we need to modify. After selecting this, we can save and exit the text editor. Git will then attempt to rebuild the branch with the selected actions.
When git encounters the commit we selected edit for, it will stop and allow modifications to the commit. The edits can be made by amending the HEAD commit (i.e. make changes and `git commit --amend`). After the commit is left in the desired state, the rebase can continue using `git rebase --continue`.
It would be nice to have a worked example here to make things a bit less abstract.
Testing a feature
After a reviewer is satisfied with all parts of a pull request, both the reviewer and the developer will perform testing on the pull request. The developer may be required to point a reviewer to a specific test case or namelist that can help the reviewer test the feature.
In addition to testing the feature, it is the reviewers responsibility to verify the pull request does not introduce issues related to the previous functionality of master. To ensure that the model still passes basic tests in multiple configurations, developers will be asked to run the e3sm_developer test suite. This can either be performed on the branch itself, or in an integration branch. The reviewer will inform the developer where testing should take place.
Basic instructions for running the e3sm_developer test suite can be found at Testing. Some additional information on testing procedures can be found at /wiki/spaces/SE/pages/7998600 and /wiki/spaces/SE/pages/3244819. Results from nightly test suites run on the "next" and "master" branches can be viewed on the ACME CDash website.
Fixing bugs in a new feature
During the testing phase, bugs may be found related to the feature. Bug fixes can be committed inline to the feature branch. This allows a bug fix to show up as an individual commit but remain part of the development history for that feature. Don't fill out a bug report for a feature that has not made it to master. Just mention the bug in the comments on the PR.
Final merge and conflict resolution
Finally, after testing is complete the reviewer is ready to merge your feature into master. When they are doing this, they might run into unexpected merge conflicts they are unable to resolve.
If they do happen to run into this situation, you may be requested to help with the process. The easiest way to help is to create a new branch at the HEAD of the branch your pull request was submitted from. This branch should have the same name as the other branch with -resolved appended to the end. After the branch is created, you can merge E3SM-Climate/E3SM/master into it, and push the resolved version onto the shared repository. This gives the reviewer a version of the code that is merged and resolved, but allows the reviewer to ensure the history maintains the standards.
Never use the github automerge! DO NOT PRESS THE GREEN BUTTON!
Merges to master will be done locally by integrators. See Integrator Guide for more info.
Additional Topics
General information for developers.
The list of "nevers":
- Never routinely merge from master to your feature branch. See below for more info.
- Never use "cherry-pick" on "next"
- Never do production simulations using "next"
- Never commit directly to "master" or "next". Only commit to your feature branch.
- Never rebase commits on your branch after it is merged to next (unless told to do so by integrator).
- Never start new development from "next".
Changing the url for your remote
After the rename of ACME-Climate/ACME to E3SM-Project/E3SM you should change url or "origin" in each clone.
First verify that "origin" is still pointing to ACME-Climate/ACME. It will unless you changed it yourself but you can check by running "git remote -v".
You'll see output like:
origin git@github.com:ACME-Climate/ACME.git (fetch)
origin git@github.com:ACME-Climate/ACME.git (push)
Change the URL for origin with this command:
git remote set-url origin git@github.com:E3SM-Project/E3SM.git
verify with "git remote -v"
origin git@github.com:E3SM-Project/E3SM.git (fetch)
origin git@github.com:E3SM-Project/E3SM.git (push)
If you have clones of other repositories that were on ACME-Climate, you'll need to update their URL's as well with similar command:
git remote set-url origin git@github.com:E3SM-Project/<repo name>.git
Working with Remote repositories
Git is a distributed content versioning system (DCVS). When you clone a repository, you make a local repository that is essentially a backup of whatever you cloned. When you commit, the commit only occurs in your local repository. In order to allow other people to make use of the commits you make, or to get your commits incorporated into master they need to be “pushed” to a remote.
A remote is a repository that you would like to communicate with, that is not in the local working directory. When you clone a repository, a default remote is created named “origin” that points to whatever you cloned. A remote is really just an alias to the location of another repository you either want to read or write with.
Before communicating with remotes, you might want to add or remove remotes. In order to add and remove remotes the git remote command can be used. The two uses are as follows:
git remote add remote-name protocol:address/to/repo # Creates a remote
git remote remove remote-name # Removes a remote
In order to communicate with remotes, there are three actions. push, pull, and fetch.
The push command can be used to write some commits from your local repository to a remote repository. For example:
git push <remote-name> <local-branch>:<remote-branch>
can be used to write a local branch to a remote branch on the remote pointed to by the name provided. An explicit example would be:
git push E3SM-Project/E3SM feature:github-username/component/feature
In this case, we’re writing the branch feature to the remote origin and changing its name to core/feature.
git push is the command used when writing history to remotes. In order to read history from remotes, the git pull and git fetch commands can be used.
The git fetch command will update the local repository with the most recent history from a specific remote, without modifying any local branches in the repository. It can be used as follows:
git fetch <remote-name>
The git pull command is a combination of two operations. The first is a git fetch in order to update the history in the local repository of the branches that exist on the remote repository. The second is a git merge which merges the changes into the current working directory. It is only recommended to use this if you know what you’re doing. It can easily cause unexpected problems. It can be used as follows:
git pull <remote-name> <branch-name>
Keeping your fork up-to-date.
You will need to keep the master branch within your fork of E3SM up to date with main version. Update as often as you want but always before you start new development or if you want to try a test PR on your fork.
Use the "Sync" button on your fork.
Avoid Routine Merges From Master
You never need to "merge from master" to make the eventual merge of your feature branch "easier" or to "keep up". Unlike svn, git is smart enough to ignore changes that have occurred in files you aren't working on when you finally merge your branch to master. Also, this practice can cause more problems.
This policy is to make it easier on developers - developers don't have to concern themselves with a hundred other things going on in E3SM and can focus solely on their feature. The integrator will evaluate how this feature works with the latest version of E3SM when they merge the feature to 'next', before it is merged to 'master'. We also don't want unnecessary merges from upstream since they just clutter and confuse the repository history and provide more opportunity to break things in the branch.
There was a discussion and several links on this topic here. To summarize some of key points:
- "frequent pulling of the \[master] into a development branch will add a certain amount of randomness to that branch; this randomness is not particularly helpful for somebody who is trying to get a feature working. It also increases the chances that another developer who ends up in the middle of the series while running a bisect operation will encounter unrelated bugs."
- A branch has a specific purpose. A topic branch 'add-frotz' would be about adding a new 'frotz' feature and shouldn't do anything else. When you merge from master, you declare that all the other unrelated changes done on 'master' in preparation for the next release somehow bring 'add-frotz' closer to the goal of the 'frotz' topic. That is usually not true
- Unnecessary merges and similar repository clutter reduces the ability to summarize, audit, notice bugs in review, and find bugs after the fact. Keeping clean history is not difficult. It requires a little bit of discipline on the part of integrators and developers, but it's a small price to pay for the time saved and improved quality/reliability.
There are some cases where merging from master (or better, a tagged version of master) can make sense. The rule of thumb for any merge is that if you can clearly describe what you are merging and why that merge is necessary for your branch to be completed, then it's fine to merge. For example, you might need a feature on master (some crucial functionality, not just a build system updates) to complete the feature on your branch. Integrators may ask you to merge from master to help resolve conflicts during a PR integration. But before merging from master, try one of the other ways to get features from other peoples development described in Incorporatinganotherbranchontoyourbranch.
If you want to see how your feature works with the latest version of master, do a test merge with a throwaway branch. Update your local version of master, make a new branch called something like "testmaster" and check it out. Merge your feature branch to this new branch (which is just a copy of master) and run your tests. When you're done, you can delete the "testmaster" branch. Repeat as necessary.
If you want to know how an Integrator would merge a branch with conflicts they can't resolve, see Integrator Guide#Resolvingmergeconflicts
On conflicts:
While git is better at handing merges and branches and resulting conflicts, do not expect that you (or the Integrator) will never encounter a merge conflict. Merge conflicts still exist, and have to be dealt with. No version control tool will be able to automatically resolve a conflict when two people change the same section of code. If two or more developers need to work on the same piece of code, or code that touches several routines, the way to avoid conflicts is to serialize the development or find the common part and do that first, then make new branches after those changes are committed.
Git branching model and avoiding conflicts:
One of the main differences between git and svn is how history and branches are stored. In svn branches are virtual directories (i.e. svn copy ^/trunk branch_name) and the history is stored as a stack of revisions (providing the monotonically increasing revision number). The problem with this is that a branch isn't actually a branch. It doesn't contain the information about where it was created from or what has been "merged" into it. The same is true when a branch is merged back into trunk; there isn't a clear historical description of what has already been integrated into trunk. (NOTE: svn has put some effort into improving their branching and merging capabilities, but they are still not up-to-par with DVCS tools)
However, in git the history is stored as a Directed Acyclic Graph (DAG), and branches are first-class citizens. The DAG structure allows any commit to determine which other commits it includes changes from (or which commits have been integrated into it). Using this history structure, git is able to ignore changes from commits that have already been integrated, reducing the number of merge conflicts that occur when bringing in a large set of changes.
Additional References on git merges
http://stackoverflow.com/a/2692999
http://stackoverflow.com/questions/2475831/merging-hg-git-vs-svn/2477089#2477089