title: Creating permanently differing changes across branches in git
body: <p>This question specifically relates to the use of git and GoogleAppEngine, but it the answer could well be of use to anyone that has branches destined for different environments.</p>
  
  <p>We are seeing an issue with unwanted code persistently cross contaminating branches during merge.</p>
  
  <p>Some Background: We are using git to manage code that's being uploaded to GoogleAppEngine. We have 3 main branches (master, staging and development) and each has it's own separate GAE project.  The standard way of deploying to GAE is via a Gradle plugin, which uses a single xml configuration file (fixed name and fixed location in the directory hierarchy) to specify the target GAE project and version number.</p>
  
  <p>e.g.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;appengine-web-app xmlns="http://appengine.google.com/ns/1.0"&gt;
      &lt;application&gt;projectname-development&lt;/application&gt;
      &lt;version&gt;307&lt;/version&gt;
      &lt;threadsafe&gt;true&lt;/threadsafe&gt;
  &lt;/appengine-web-app&gt;
  </code></pre>
  
  <p>So, this file has been modified on each branch to have the correct <code>-live</code> and <code>-staging</code> postfixes to the <code>&lt;application&gt;</code> tag.</p>
  
  <p>Our work process is complex, but not unusual.  New features are branched from development and merged back into development (--no-ff so we can see the branch history).  Development is then merged into staging.  Staging is merged into master.  Bug fixes to staging are branched to a bugfix branch, then merged back to staging and backward to development.</p>
  
  <p>Our problems are occurring when we start merging between the primary branches or bugfix to development branch.  git resolves the merge by replacing the GAE target project in the XML most of the time.  I could understand this on the first merge (because this is where it became divergent), but we perform the merge with --no-ff and --no-commit so we can update the version numbers correctly (as they get incremented as part of our merge policy) and git appears to be trying to merge the incorrect content every time merge is used.</p>
  
  <p>The 'psuedocode' for this problem would be as follows:-</p>
  
  <p>Create initial branches...<br>
  1. Commit xml file to master.<br>
  2. Branch master to development<br>
  3. Change GAE target project in the xml in development and commit</p>
  
  <p>Develop a feature...<br>
  4. Create feature branch from development, make feature, increase version number, merge back to development<br>
  5. Merge development to master with --no-ff and --no-commit</p>
  
  <p>At this point, as expected it will merge the GAE target project and version from development to master.  We manually correct GAE target project back to what it was on the master branch, but leave the change to version number; and commit.</p>
  
  <p>Develop another feature...<br>
  6. Create feature branch from development, make feature, increase version number, merge back to development<br>
  7. Merge development to master with --no-ff and --no-commit</p>
  
  <p>At this point, things are not as expected.  Git has changed both the version number <strong>and the GAE target project</strong>.  Without trying it, I'm 99.9% sure that other source control (SVN, Vault or Perforce in my experience) would have only merged the version number, which is the outcome I would have expected here.</p>
  
  <p>We didn't initially notice the issue because SourceTree was hiding changes from us (not shown in the log at all?!).  It was only when performing this from command line and looking at every step along the way that we noticed where the issue was coming from.  It's almost like git is being too clever and it's figuring that as we've not committed that hunk (because we manually edited the file before commit) that we have done some sort of cherry pick and it tries to do a deferred merge at a later stage.</p>
  
  <p>So, my question is "How do we tell git that when we have committed our merged file from branch B to branch A, that we have taken all the changes from it we want?", or is there a better/different solution to this problem?</p>