922 lines
44 KiB
Plaintext
922 lines
44 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
|
|
<title>JMRI: Git FAQ</title>
|
|
<meta name="author" content="Bob Jacobsen">
|
|
<meta name="keywords" content="JMRI technical code Git FAQ">
|
|
<!--#include virtual="/help/en/parts/Style.shtml" -->
|
|
<!-- FAQ-Head -->
|
|
|
|
<script type="text/javascript">
|
|
/*<![CDATA[*/document.documentElement.className="hasJS";/*]]>*/
|
|
</script>
|
|
<link rel="stylesheet" type="text/css" href="https://www.jmri.org/web/css/faq.css" media="screen"><!-- /FAQ-Head -->
|
|
</head>
|
|
<body>
|
|
<!--#include virtual="/help/en/parts/Header.shtml" -->
|
|
|
|
<div id="mBody">
|
|
<!--#include virtual="Sidebar.shtml" -->
|
|
|
|
<div id="mainContent">
|
|
<h1>JMRI Code: Git FAQ</h1>
|
|
|
|
<p>This is a list of Frequently Asked Questions for Git, particularly regarding how we use it
|
|
with JMRI.<br>
|
|
Click on a question to open the answer.</p>
|
|
|
|
<p>There's a <a href="getgitcode.shtml">separate JMRI Help page</a> on how to <a href=
|
|
"getgitcode.shtml">get the code with Git</a>.</p>
|
|
|
|
<p>See also the <a href="index.shtml">Technical index</a> for more information on maintaining
|
|
JMRI code.</p>
|
|
|
|
<p>See also the <a href="../../FAQ.shtml">JMRI general FAQ.</a></p>
|
|
|
|
<h2>Common User Topics</h2>
|
|
|
|
<dl class="faq">
|
|
<dt id="install" class="on">How do I install Git?</dt>
|
|
|
|
<dd>
|
|
Git is free software. Depending on your computer type and your preferences, there are
|
|
several ways to install it. There's more info in the Git community's <a href=
|
|
"https://git-scm.com/book/en/v2/Getting-Started-Installing-Git">Getting Started</a>
|
|
guide.
|
|
<ul>
|
|
<li>Get it from the <a href="https://git-scm.com/downloads" target="_blank">Git download
|
|
page</a>.
|
|
</li>
|
|
|
|
<li>It comes with the GitHub Desktop application, available from the <a href=
|
|
"https://desktop.github.com" target="_blank">Git desktop download page</a> (OS X and
|
|
Windows only).See <a href="githubdesktopintro.shtml">here for an intro.</a>
|
|
</li>
|
|
|
|
<li>On the Mac, it's included when you <a href=
|
|
"https://developer.apple.com/xcode/download/">install Xcode</a> ( requires Apple Developer ID to Sign in ).
|
|
</li>
|
|
|
|
<li>On Linux you can use your package installer, e.g. <code>sudo yum install git</code>
|
|
or <code>sudo apt-get install git</code>.</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt>Setting up a Git environment for JMRI Developers</dt>
|
|
|
|
<dd>
|
|
You can set your local repository to pull automatically from the JMRI master on GitHub
|
|
and push to your fork (also on GitHub):<br>
|
|
<a href="https://www.jmri.org/web/images/GitHubWorkflow.png"><img src="https://www.jmri.org/web/images/GitHubWorkflow.png"
|
|
height="25%" width="25%" alt="GitHub Work Flow"></a>
|
|
<p>That horizontal arrow is the "Pull Request" (and subsequent pull) that records
|
|
information about how things get into the repository.</p>
|
|
|
|
<p>The arrows are both operations (push, pull) and also definitions of <em>where</em> to
|
|
look e.g. a URL. Git can store shorthand for a URL, called a "remote". The default remote
|
|
is called "origin". You can have many remotes defined.</p>
|
|
|
|
<p>Via the git command line tool you do this with this command:</p>
|
|
<div class="wide">
|
|
<pre>
|
|
$ git remote set-url --push origin https://github.com/<em>username</em>/JMRI.git
|
|
</pre></div>
|
|
where <code>username</code> is your github user name. You can check the current status with
|
|
of the push and pull repositories with:
|
|
<div class="wide">
|
|
<pre>
|
|
$ git remote -v
|
|
origin https://github.com/JMRI/JMRI.git (fetch)
|
|
origin https://github.com/<em>username</em>/JMRI.git (push)
|
|
</pre></div>
|
|
<p>This says that, by default, fetches and pulls come from the main JMRI/JMRI repository. When
|
|
you push, on the other hand, it goes to your own repository.<br>
|
|
Once you have a copy of your changes on GitHub, it is easy to <a href=
|
|
"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request"
|
|
>generate a Pull Request</a> (link to GitHub)</p>
|
|
|
|
<ul>
|
|
<li>In a browser, navigate to your repository on GitHub that has the changes you want
|
|
someone else to pull and</li>
|
|
|
|
<li>press the green compare icon <img src="https://www.jmri.org/web/images/GitHubPR1.png" alt=
|
|
"GitHub PR1">, then click on Create Pull Request.</li>
|
|
|
|
<li>After your pull request has been reviewed, it can be merged back in to the main
|
|
JMRI/JMRI repository. The JMRI developer who "pulls" your changes into the community
|
|
source needs to have access to an online repository that has your changes, which is why
|
|
you need to have a place on GitHub in the first place...</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt id="working">Working with Git</dt>
|
|
|
|
<dd>
|
|
<p>With SVN and CVS, you check out a "working directory" to make your changes in, work in
|
|
it for a while, and eventually commit all your changes back to the main repository.</p>
|
|
|
|
<p>Git works on a different idea. Instead of multiple working directories, you have a
|
|
single repository that's been "cloned" from the main repository. If you're making
|
|
individual little changes, you can work directly on the default "master" branch within
|
|
it. If not, see <a href="#branch">Using Branches</a>, below.</p>
|
|
|
|
<p>To understand Git, it is good to know about the various <em>places</em> in your local
|
|
git repository:</p>
|
|
|
|
<ul>
|
|
<li>The content from the "remote" repo, which lives under the <code>.git/</code> hidden
|
|
directory,</li>
|
|
|
|
<li>The "staging" area (also called "index" or "cache"), and</li>
|
|
|
|
<li>The named "branch" you are using, which lives in</li>
|
|
|
|
<li>The working tree.</li>
|
|
</ul>
|
|
|
|
<p>When you <em>clone</em> a git repo, you are creating a directory structure that holds
|
|
all of these items. Unless you tell it otherwise, the working tree starts off filled with
|
|
contents of the <em>master branch</em> of the repo you cloned - and the <em>staging
|
|
area</em> is empty. As you make changes to the files in the working tree, you need to
|
|
explicitly <em>add</em> them to the staging area. Git knows about these files, but they
|
|
aren't yet officially part of your local repo.</p>
|
|
|
|
<p>Once you have populated the staging area with of all the things you have changed, a
|
|
<em>commit</em> operation will, uhm, officially commit your changes to your repo's
|
|
<code>.git/</code> structure.</p>
|
|
|
|
<p>When you <em>pull</em> or <em>push</em>, you are telling Git to synchronize your
|
|
<code>.git/</code> content with that of the remote repo you originally cloned things
|
|
from.</p>
|
|
|
|
<h3>Getting Started</h3>
|
|
<p>The first step is to log in to GitHub and clone your own copy of the main JMRI repo. This
|
|
will give you a safe place to push and pull from without impacting others.</p>
|
|
|
|
<h4>Using Git from the command line</h4>
|
|
|
|
<ul>
|
|
<li>Clone the JMRI repo to your local system (or update it):
|
|
|
|
<pre style="font-family: monospace;">
|
|
$ git clone https://github.com/JMRI/JMRI.git
|
|
</pre>
|
|
<p>or</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
$ git fetch
|
|
</pre>
|
|
<p>then</p>
|
|
<div class="wide">
|
|
<pre style="font-family: monospace;">
|
|
$ git diff ...origin
|
|
$ git merge origin/master
|
|
Auto-merging ... files ...
|
|
CONFLICT (content): Merge conflict in <em>some_file</em>
|
|
Automatic merge failed; fix conflicts and then commit the result.
|
|
$ vi <em>some_file</em> # the file has the conflicts marked, edit to fix...
|
|
$ git add <em>some_file</em>
|
|
$ git commit -m "Merged master fixed conflict"
|
|
$ git merge origin/master
|
|
</pre></div>
|
|
<p>or</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
$ git pull https://github.com/JMRI/JMRI.git
|
|
</pre>
|
|
</li>
|
|
|
|
<li>Make your changes locally, test them, etc.
|
|
|
|
<pre style="font-family: monospace;">
|
|
$ git add <em>newfile</em>
|
|
$ git rm <em>oldfile</em>
|
|
$ git add .
|
|
|
|
$ git status
|
|
|
|
$ git fetch
|
|
$ git merge
|
|
</pre>
|
|
</li>
|
|
|
|
<li>Make your changes available to the community
|
|
<div class="wide">
|
|
<pre style="font-family: monospace;">
|
|
$ git commit -m <em>"commit message"</em> <em>filename</em>, <em>filename</em>
|
|
</pre></div>
|
|
|
|
<p>or</p>
|
|
<div class="wide">
|
|
<pre style="font-family: monospace;">
|
|
$ git commit -a -m <em>"commit message"</em>
|
|
</pre></div>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Using GitHub Desktop application</h4>
|
|
<p>GitHub Desktop is a free application that can do many of the same things that the git
|
|
command-line tool does, but provides an interface that many people find easier and more
|
|
friendly.</p>
|
|
<p>For more on GitHub Desktop, please see our <a href="githubdesktopintro.shtml">page on
|
|
using GitHub Desktop</a>.</p>
|
|
|
|
<ul>
|
|
<li>Clone the JMRI repo to your local system by picking an item from the "Clone" tab in
|
|
the File -> Clone repository... menu and clicking "Clone":<br>
|
|
<a href="images/GhDtCloneDialog.png"><img src="images/GhDtCloneDialog.png"
|
|
alt="GitHub Desktop PR dialog"></a>
|
|
</li>
|
|
|
|
<li>Check your GitHub URL in the "Remote" tab from the Repository -> Repository
|
|
Settings menu as:<br>
|
|
<a href="images/GhDtRepoSetting.png"><img src="images/GhDtRepoSetting.png"
|
|
alt="GitHub Desktop Repo Setting"></a>
|
|
</li>
|
|
|
|
<li>Make your changes locally, test them, etc.<br>
|
|
When it all works, <em>commit</em> your edit to your local JMRI repository by
|
|
returning to the GitHub Desktop application, reviewing all changes noticed by the
|
|
program, enter a Summary [1] and Description [2] and finally clicking the Commit to
|
|
<branch> [3] button:<br>
|
|
<a href="images/GhDtWindow.png"><img src="images/GhDtWindow.png"
|
|
alt="GitHub Desktop Window"></a>
|
|
<p>After your Commit, a white dot will appear near the end of the line that looks
|
|
like a siding in a <em>track plan</em>. Click it to read the title. To see the files
|
|
changed at another point in time, click an older commit dot:<br>
|
|
<a href="images/GhDtWindowSeeCommit.png"><img src="images/GhDtWindowSeeCommit.png"
|
|
alt="GitHub Desktop Commit"></a></p>
|
|
|
|
<p>After a commit, your new edits are only added to your local copy of your branch.
|
|
To have them show up in a place other people can see them, either click the
|
|
<strong>Sync</strong> button at top right, choose Sync (Cmd-S) from the Repository
|
|
menu or make Github Desktop automatically sync after every commit by checking the
|
|
Automatically Sync after Committing menu item in the Edit menu:<br>
|
|
<a href="images/GhDtSyncSetting.png"><img src="images/GhDtSyncSetting.png"
|
|
alt="GitHub Desktop auto sync menu"></a></p>
|
|
</li>
|
|
|
|
<li>When you've worked on something in GhDt for a week or more, other people definitely
|
|
have worked on other parts of JMRI. To integrate these new data into your copy, click
|
|
the <strong>Update from JMRI/master</strong> button in the top left of the pane (or
|
|
choose "Pull" from the "Repository" menu).<br>
|
|
You will see an animation of a small branch symbol in a circle, moving from the
|
|
straight white line down to the line below it:<br>
|
|
<a href="images/GhDtUpdateFrom.png"><img src="images/GhDtUpdateFrom.png"
|
|
alt="GitHub Desktop Pull"></a>
|
|
<p>This tells you that new code has been copied to your repo, and in a few seconds
|
|
this new code is also copied to your computer, so you can view it or use it, unless
|
|
they've been working on the same lines of code (See Resolve a Merge Conflict,
|
|
below)</p>
|
|
</li>
|
|
|
|
<li>To make your changes available to the community click "Pull Request" (top right
|
|
button), enter a title and click "Create".<br>
|
|
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
<a href="images/GhDtPRCreate.png"><img src="images/GhDtPRCreate.png"
|
|
alt="GitHub Desktop Create PR dialog"></a>
|
|
</td>
|
|
<td>The name of the PR button will change into <strong>#123</strong><br>
|
|
signaling you can't make another PR in this branch<br>
|
|
from here (but you can still commit extra edits to it):</td>
|
|
<td>
|
|
<a href="images/GhDtPRCreated.png"><img src="images/GhDtPRCreated.png"
|
|
alt="GitHub Desktop PR Created message"></a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p>Normally, a PR is meant for the master branch of the _original_ repo, say
|
|
JMRI:master. You may pull your PR in your own remote repo, but only a couple of
|
|
people, the maintainers, can pull your edits into the "real" JMRI:master. Before they
|
|
do that, they study what you've written, maybe even pull it into their own repo to
|
|
test it before merging it for every other JMRI user to see.<br>
|
|
When your PR is pulled & merged & closed, the PR #123 name will disappear and you may
|
|
delete the branch safely.</p>
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt id="branchexamples">Branch Examples</dt>
|
|
|
|
<dd>
|
|
<img src="images/git_branch_baseline.png" class="floatRight" alt="Branch Baseline"> The
|
|
figure to the right shows a couple examples of how we use branches in Git. The black line
|
|
going from left to right is the "master" branch. Each dot on it is a change that somebody
|
|
made on the master branch.
|
|
<p>At the left, the blue rectangle shows how a change can be made.</p>
|
|
|
|
<ul>
|
|
<li>Somebody created a new branch (the colored line)</li>
|
|
|
|
<li>That person made a change on their new branch (colored dot)</li>
|
|
|
|
<li>And then, through the PR process, that was merged back onto the master branch
|
|
(rightmost black dot).</li>
|
|
</ul>
|
|
|
|
<p>That basic process is used to make all the changes to the master branch, although for
|
|
simplicity we haven't shown all the details for all of them.</p>
|
|
<p>Sometimes, your development work can take a while. Maybe you do it in several phases,
|
|
making multiple commits. Before you're finally ready to merge it back into the common
|
|
code with via a Pull Request (PR), somebody else can make a change on the master branch.
|
|
The green path shows that case. The branch was created, development took some time, and
|
|
then a change was made to master (black dot on black line) before the green change was
|
|
merged back. The merge process in the green arrowhead took care of this. Generally, this
|
|
is straightforward, because most of the code doesn't change very often: If just a couple
|
|
changes have been made, they rarely overlap. This motivates our "merge often" philosophy.
|
|
<img src="images/git_branch_merge_master.png" class="floatRight" alt="Branch merge"></p>
|
|
|
|
<p>Sometimes development goes on for such a long time that people made changes to master
|
|
that matter to you. Perhaps they're new features or bug fixes that you'd like to have in
|
|
your own development branch. Or perhaps they're changes that conflict, and you'd like to
|
|
resolve those conflicts in your own work now, rather than waiting for later.</p>
|
|
|
|
<p>The 2nd diagram to the right has an example of this. After the programmer created the
|
|
blue branch for his own work, changes were made on both his branch (first three dots on
|
|
blue line) and on master (three dots on black line). Sometime after that 3rd change on
|
|
master, the developer decided to "git merge master" onto his branch, bringing all those
|
|
changes in via the black diagonal arrow. Both his changes and the changes to master are
|
|
now present in the blue branch he's working on.</p>
|
|
|
|
<p>Later, he decides to merge his work back onto master via the blue arrow in the
|
|
middle.</p>
|
|
|
|
<p>But at that point, he can still continue to work on his branch (next blue dot).
|
|
Perhaps he's fixing a bug that was found by a user once the work was merged to master. Or
|
|
perhaps he's just working more in the same direction. Either way, when he's ready, he can
|
|
merge again (right-most blue diagonal), or keep working on his branch (blue line running
|
|
off to right), or merge other people's work to his branch once it's merged (not
|
|
shown).</p>
|
|
|
|
<p>By doing your work on your own branch:</p>
|
|
|
|
<ul>
|
|
<li>You get control over when you want to merge in other people work. You can hold off
|
|
on that as long as you want, even distributing your own version if you want to.</li>
|
|
|
|
<li>At the same time, you can merge your work into the master branch shared by others
|
|
whenever it's ready, without disrupting your own work: Your branch is unchanged by
|
|
merging it with master.</li>
|
|
</ul>
|
|
More complicated diagrams are possible, with branches from branches to work
|
|
collaboratively, etc. You can see <a href="https://github.com/JMRI/JMRI/network">JMRI's
|
|
entire branch graph</a> on the GitHub site.
|
|
<p>The basic idea is important: By working on a branch in your repository, your work can
|
|
be kept a part of the overall JMRI effort instead of being isolated and unavailable.</p>
|
|
</dd>
|
|
|
|
<dt id="branch">Using Branches</dt>
|
|
|
|
<dd>
|
|
Always work on a named <em>branch</em>, never on the one named "master". Though you can
|
|
work directly on the default "master" branch, good "Git Hygiene" encourages you to create
|
|
a feature branch so you can work on it and never mess up your local copy of JMRI:master.
|
|
Branches in Git are easy and cheap to create and use; you can have multiple branches at
|
|
the same time, and switch between them as you work on different projects.
|
|
<p>We recommend that you name branches starting with your GitHub account name or initials
|
|
(for example, "abc") and something that suggests what you are working on:
|
|
<code>"abc-decoder-xml-change"</code>, <code>"abc-2015-09-14"</code>,
|
|
<code>"abc-next-cool-thing"</code>, and <code>"abc-patch-NNNN"</code> are all fine. That
|
|
way, we know it's you, and you can sort out the rest. Keep the name short & simple enough
|
|
to easily type (because people will sometimes have to), and limit it to letters, numbers
|
|
and use the "-" instead of spaces; that'll make it easier to work with.</p>
|
|
|
|
<ul>
|
|
<li>Using git:
|
|
<ul>
|
|
<li>To create a branch called "<em>branchname</em>", you do<br>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout -b <em>branchname</em>
|
|
</pre>
|
|
The "-b" says to create the branch. To switch to an existing branch, just leave out that
|
|
option:<br>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout <em>branchname</em>
|
|
</pre>To see all the current branches, do<br>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git branch
|
|
</pre>
|
|
</li>
|
|
|
|
<li>If other people in the community make changes to the master branch, you can
|
|
keep your branch up to date by merging those changes in with your branch<br>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout <em>branchname</em>
|
|
git merge -m"merging in current contents of master" master
|
|
</pre>
|
|
(If you leave off the message option, you may be prompted to add one in an editor) If any
|
|
changes were picked up and merged in, you can then commit them to your branch:
|
|
|
|
<pre style="font-family: monospace;">
|
|
git commit -a
|
|
</pre>
|
|
</li>
|
|
|
|
<li>
|
|
<p>When you're done, merge your changes back into the common line of development
|
|
with<br></p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout master
|
|
git merge -m"merging to master" <em>branchname</em>
|
|
git commit -a
|
|
</pre>
|
|
</li>
|
|
|
|
<li>You can then delete your branch (if you're finally done with it) with<br>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout master
|
|
git branch -d branchname
|
|
</pre>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>Using GitHub Desktop:
|
|
<ul>
|
|
<li>Click the "Add a Branch (+)" button, provide a name for your new branch and
|
|
using the From: pop-up, select the branch from where you want to create the new
|
|
branch:<br>
|
|
<a href="images/GhDtNewBranch.png"><img src="images/GhDtNewBranch.png"
|
|
alt="GitHub Desktop Repo Setting"></a>
|
|
</li>
|
|
|
|
<li>To delete a branch, select it in the "Show Branches" pop-up menu, and then
|
|
select <strong>Delete "my-patch"</strong> from the Branch menu.<br>
|
|
You can't do that with the master branch, so don't work in that, always work in a
|
|
named branch.<br>
|
|
<a href="images/GhDtDeleteBranch.png"><img src="images/GhDtDeleteBranch.png"
|
|
alt="GitHub Desktop Repo Setting"></a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>You can opt to create and delete branches in Github web just as easily. More help
|
|
on <a href=
|
|
"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository">
|
|
Github Web Branching</a>.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt id="share">Sharing Branches</dt>
|
|
|
|
<dd>
|
|
One of the advantages of Git branches is that it's easy for people to share them. This
|
|
lets one person work with something that another has done, including editing and
|
|
improving it, without it having to be released to everybody.
|
|
<p>Say Arnie has developed something on the "arnie-great-tool" branch. Bill wants to try
|
|
to use it on his layout. The steps are:</p>
|
|
|
|
<ol>
|
|
<li>Arnie commits it to local repository, and then pushes it to his GitHub repository.
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout arnie-great-tool
|
|
(work on changes)
|
|
git commit -m"Added support for the Frobnab 2000"
|
|
git push
|
|
</pre>
|
|
</li>
|
|
|
|
<li>Bill can then get that by pulling it from Arnie's repository.
|
|
|
|
<pre style="font-family: monospace;">
|
|
git remote add arnie https://github.com/arnie/JMRI.git
|
|
|
|
git fetch arnie arnie-great-tool
|
|
git checkout arnie-great-tool
|
|
</pre>where the 2nd part of the "remote add" is the URL for Arnie's repository, and you just have
|
|
to do that command once to define "arnie" as an alias you can use in "git fetch".
|
|
</li>
|
|
|
|
<li>Now Bill can work with that code, and even change it as needed. If he makes changes
|
|
that he wants Arnie to have, he does the same process in reverse:
|
|
|
|
<pre style="font-family: monospace;">
|
|
git commit -m"Fixed a bug in sternerstat handling"
|
|
git push
|
|
</pre>which commits the changes and pushes them up into Bill's repository on Github.
|
|
<p>Then Arnie can merge those changes into his own copy with:</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout arnie-great-tool
|
|
git pull https://github.com/bill/JMRI.git arnie-great-tool
|
|
</pre>
|
|
</li>
|
|
</ol>
|
|
</dd>
|
|
|
|
<dt id="resolve">Resolving a Merge Conflict</dt>
|
|
|
|
<dd>
|
|
It's not uncommon for two or more people to have ideas about the same part of the program
|
|
or the JMRI website, each making commits and PR's for parts of the same files. If they
|
|
were working on different lines of text or code in one file, GitHub knows how to combine
|
|
those changes into one updated file. You may have to check your proposal still works, as
|
|
someone might have deleted the anchor you were referring to etc. If GHDt discovers that a
|
|
change from one person was inserted into master, and you have prepared changes to the
|
|
same line, GitHub Desktop asks you to help decide what to do by displaying the following
|
|
Conflict screen (Note the orange dots next to one of the file names):<br>
|
|
<a href="images/GhDtConflictNote.png"><img src="images/GhDtConflictNote.png"
|
|
alt="GitHub Merge Conflict Note"></a>
|
|
<p>Click on that name and choose Show in Finder or Open with External Editor (GhDt itself
|
|
has no edit tools).<br>
|
|
To find the spot where the Conflict occurred, look for the <code><<< HEAD ====
|
|
>>> master</code> markers that were inserted by GitHub:<br>
|
|
<a href="images/GhDtConfictmark.png"><img src="images/GhDtConfictmark.png"
|
|
alt="GitHub Merge Conflict marking in code"></a><br>
|
|
Choose which of both versions you wish to keep (or make some combination) and remove the
|
|
<code>< === ></code> lines!<br>
|
|
<a href="images/GhDtConflictFixed.png"><img src="images/GhDtConflictFixed.png"
|
|
alt="GitHub Merge Conflict solved in code"></a></p>
|
|
|
|
<p>This new proposal should still be Committed to JMRI, so give it a fitting title i.e.
|
|
"Solve conflict" and click Commit (and Sync). This extra commit will be added to your PR
|
|
and be part of your proposal the maintainers will see. You shouldn't keep merge conflict
|
|
lurking overnight, as the maintainers have no way to fix them for you and they will have
|
|
to ignore it till you solved it.</p>
|
|
</dd>
|
|
|
|
<dt id="ci-tests">Continuous Integration Tests</dt>
|
|
|
|
<dd>
|
|
The main JMRI repositories run a set of tests on every Pull Request (PR). This is called
|
|
Continuous Integration (CI), and is a time-proven method to keep code quality up.
|
|
<p>You can add this to your repositor(ies) so that each push will get automatically
|
|
tested.</p>
|
|
|
|
<p>The two CI test services are "Travis CI" and "GitHub":</p>
|
|
|
|
<ul>
|
|
<li>Travis CI runs on Linux. It first does a check for wrong line ends (see <a href=
|
|
"#lineends">later section</a>), then runs the complete set of JUnit tests, including
|
|
testing screen operations.
|
|
</li>
|
|
|
|
<li>GitHub runs multiple operating systems.</li>
|
|
</ul>
|
|
To add these to your own repository:
|
|
<ul>
|
|
<li>For Travis CI, go to the <a href="https://www.travis-ci.com">Travis CI web page</a> and
|
|
"Sign Up". Use your GitHub account and email. At the end of that process, it will ask
|
|
you which of your GitHub repositories to monitor; you can select both the "JMRI" and
|
|
"website" forks.
|
|
</li>
|
|
|
|
<li>GitHub is automatically available and working on personal forks.</li>
|
|
</ul>
|
|
From then on, pushing to your own repository will run the tests. You'll get an email when
|
|
the tests are complete, or you can check on the web.
|
|
</dd>
|
|
|
|
<dt id="lineends">Handling Line Ends</dt>
|
|
|
|
<dd>
|
|
Mac and Linux use a LF character at the end of each line; Windows uses the CRLF pair.
|
|
JMRI's text files are, by convention, stored in Git with LF line ends.
|
|
<p>It's very important that Windows users not accidentally convert a file to CRLF line
|
|
ends. When that happens, Git thinks that every line has been changed: Git can no longer
|
|
provide useful, granular history information about earlier changes to the file.</p>
|
|
|
|
<p>There is a ".gitattributes" file that tells (most) command-line Git implementations
|
|
how to handle this properly. Unfortunately, not all IDEs obey the directives in the file.
|
|
For example, to get NetBeans on Windows to handle line-ends properly, a specific plugin
|
|
must be installed. See the <a href="NetBeans.shtml#windows">NetBeans JMRI help page</a> for
|
|
specifics.</p>
|
|
|
|
<p>If a file with changed line-ends is accidentally committed and forwarded in a
|
|
pull-request (PR), the bad file in that PR will be detected during the Travis CI test and
|
|
the PI will <strong>not</strong> be accepted and merged. Further, the PR will be marked
|
|
with a "CRLF" label. Since the history has already been lost in this file, the CRLF label
|
|
reminds the maintainers that it's not sufficient to just change the line-ends back to LF,
|
|
commit and push: The history has been <u>lost</u>, and more complicated measures must be
|
|
taken.<br>
|
|
The two approaches are:</p>
|
|
|
|
<ol>
|
|
<li>Abandon the PR and underlying edits, delete the branch, and redo it right. If
|
|
you're working properly, with your changes in a separate branch, and committing small
|
|
changes, this is the recommended course of action.</li>
|
|
|
|
<li>Alternately, it's possible to use Git tools to remove the improper commit(s) from
|
|
the branch. This is much more complicated. Get one of the developers with Git expertise
|
|
to do it for you, and then send them cookies as a thank-you.</li>
|
|
</ol>
|
|
|
|
<p>Maintainers who encounter an updated PR with the CRLF label should check to see that
|
|
all the files in the PR do <u>not</u> show all lines changed. If they do, even if they
|
|
have the correct LF line ends, the PR should not be merged.</p>
|
|
|
|
<p>Many <a href="XmlEditors.shtml">XML Editors</a> have a Preference Setting for line
|
|
ends.<br>
|
|
For example, in Espresso check that Line Endings are set to <strong>Unix (LF)</strong>
|
|
before starting to edit any JMRI file:<br>
|
|
<a href="images/EspressoPrefsLF.png"><img src="images/EspressoPrefsLF.png"
|
|
alt="Espresso LF Preference setting"></a></p>
|
|
</dd>
|
|
|
|
<dt id="testPR">Testing a Pull Request</dt>
|
|
|
|
<dd>
|
|
<p>Pull requests are just a special case of a branch. If you want to test them before
|
|
merging them into master, you can bring them into your local repository and work with
|
|
them. <a href="images/GitHubPullPRLinks.png"><img src="images/GitHubPullPRLinks.png"
|
|
class="floatRight" alt="GitHub Web PR screen"></a></p>
|
|
|
|
<p>In some cases, GitHub Web makes specific instructions available right on the
|
|
pull-request itself. Look near the bottom of the discussion thread, in the last
|
|
information block. The nice thing about those is that they automatically have the right
|
|
branch names, etc, included.</p>
|
|
|
|
<p>Please note that, in some cases, these have a "Step 1" for looking at the pull request
|
|
locally, and a "Step 2" for merging it back. Please do not do that Step 2 request from
|
|
the command line, but instead use the web interface for doing the actual merge.</p>
|
|
|
|
<p>If no instructions are displayed, here's the sequence of things to do:</p>
|
|
|
|
<ul>
|
|
<li>Find the source repository and branch name. To do this, look at the top of the
|
|
branch request for a line that says:
|
|
<blockquote>
|
|
<u>user</u> wants to merge <u>3</u> commits into JMRI:master from
|
|
<u>user</u>:<u>branch</u>
|
|
</blockquote>
|
|
<a href="images/GitHubPRbranchInfo.png"><img src="images/GitHubPRbranchInfo.png"
|
|
alt="GitHub Web branch screen"></a>
|
|
</li>
|
|
|
|
<li>Next, pull that branch onto your own machine with the command:
|
|
<div class="wide">
|
|
<pre style="font-family: monospace;">
|
|
git fetch https://github.com/<u>user</u>/JMRI.git <u>branch</u>:<u>local-branch</u>
|
|
</pre></div>
|
|
where you have to replace each underlined value:
|
|
<ul>
|
|
<li>Change "user" to the correct GitHub user name</li>
|
|
|
|
<li>Change "branch" to the name of the branch in the pull request (it's OK if this
|
|
is e.g. master)</li>
|
|
|
|
<li>Change "local-branch" to what you want to call the branch on your own machine.
|
|
<em>This must not exist already</em>. Something like "me-user-branch" will remind
|
|
you of whose repository you pulled it from, while marking as subsequent changes as
|
|
yours if you later share it with somebody else. (It's recommended that people start
|
|
their branch names with their own name, which simplifies all sorts of
|
|
operations)</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>The branch now exists in your machine, and you can just move to it:
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout <u>local-branch</u>
|
|
</pre>then compile, test, etc. as you'd like. You can even commit and share changes if you'd like,
|
|
because this is now your own development branch: It started at the other person's, but it's now
|
|
your own.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt id="bisect">Using "git bisect" to find the cause of a bug</dt>
|
|
|
|
<dd>
|
|
If you have a reproducible problem that you think was introduced by a change to the code,
|
|
"git bisect" can help you track down the commit that caused it. It's very efficient at
|
|
tracking down repeating problems due to a single change.
|
|
<p>Let's say that you know <code>v4.9.1</code> does not have the problem, and commit
|
|
<code>23482341</code> (made up number) does. A narrow range is good, but don't spend any
|
|
time on it; git bisect does a binary search that's very efficient. Then you check out the
|
|
bad version:</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git checkout 23482341
|
|
</pre>You start the bisect process:
|
|
|
|
<pre style="font-family: monospace;">
|
|
git bisect start
|
|
git bisect bad
|
|
git bisect good v4.9.1
|
|
</pre>
|
|
<p>I.e. set up your branch <u>with</u> the problem, start 'git bisect', tell it the problem is
|
|
visible here and now, then tell it where there's a good version to search through. Git will sort
|
|
out the possible revision path(s) where the problem can lie and devise an optimal search. Then it
|
|
will checkout some place in the middle and tell you "Bisecting: 6 revisions left to test after
|
|
this" or something like this.</p>
|
|
<p>Test that code:</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
ant clean tests
|
|
</pre>(and whatever you need to recreate). Once you know if it's good or bad, you say
|
|
|
|
<pre style="font-family: monospace;">
|
|
git bisect good
|
|
</pre>
|
|
<p>or</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git bisect bad
|
|
</pre>and repeat. Git will do a good job of giving you the minimal number of tests to do, and in
|
|
the end will show you the commit that turned "good" into "bad" - not the PR, the single commit. You
|
|
can then look at the exact changes in that commit to see what went wrong.
|
|
<p>After "git bisect" is finished, end the process with</p>
|
|
|
|
<pre style="font-family: monospace;">
|
|
git bisect reset
|
|
</pre>to get back to where you started.
|
|
</dd>
|
|
|
|
<dt id="SFnetPatches">Handling a GitHub contributed file or SF.net Patch</dt>
|
|
|
|
<dd>
|
|
Sometimes people contribute files via the <a href=
|
|
"https://sourceforge.net/p/jmri/patches/">SF.net issue tracker</a> or a <a href=
|
|
"https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues"
|
|
>GitHub Issue</a>. This discussion talks about how to handle those.
|
|
<ol>
|
|
<li>In your local repository, create a branch to hold the patch:
|
|
<blockquote>
|
|
<code>git checkout -b patch-NNNN</code>
|
|
</blockquote>
|
|
where NNNN is the patch number.
|
|
</li>
|
|
|
|
<li>Merge in the changed code as needed.</li>
|
|
|
|
<li>Commit your changes:
|
|
<blockquote>
|
|
<code>git commit -m"Patch-NNNN plus the patch subject line (author name)"</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>It's now in your repository on a branch of its own, where you can sanity test
|
|
things as usual.</li>
|
|
|
|
<li>When you are happy, push your local repo's committed content to your GitHub
|
|
repository (assuming the default configuration, where "push" goes to your own
|
|
repository on GitHub) with
|
|
<blockquote>
|
|
<code>git push origin patch-NNNN</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>Go to your repository on GitHub and start the "pull request" process.</li>
|
|
|
|
<li>On the second screen, switch the branch being compared in your repository from
|
|
"<strong>master</strong>" to "<strong>patch-NNNN</strong>". Then the rest of the pull
|
|
request goes as before.</li>
|
|
|
|
<li>Eventually, a JMRI maintainer will handle the pull request and merge it, which will
|
|
put the patch changes on the master branch in the repository.</li>
|
|
|
|
<li>You can wait for the merge to the main repository, and then perform a
|
|
<blockquote>
|
|
<code>git pull</code>
|
|
</blockquote>
|
|
to update your local repository with this patch on the master branch. Or, if you need
|
|
them sooner, you can immediately merge these changes onto your local master via
|
|
<blockquote>
|
|
<code>git checkout master<br>
|
|
git merge patch-NNNN<br></code>
|
|
</blockquote>
|
|
</li>
|
|
</ol>
|
|
The advantage of this approach is that it lets you keep all your own work separate from
|
|
any patches you're handling. The patches are on different branches than your work, so
|
|
they don't overlap.
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2>Less-Common Operations</h2>
|
|
|
|
<dl class="faq">
|
|
<dt id="migrateSVN">Migrating un-committed changes from a SVN checkout</dt>
|
|
|
|
<dd>
|
|
<p>As we migrated from SVN to Git in late 2015, you may still have edits based on old
|
|
code. If you have changes to the JMRI code in an existing SVN checkout that you wish to
|
|
commit to the current development version in Git, here's what we recommend:</p>
|
|
|
|
<ol>
|
|
<li>"Update" to the HEAD of SVN. You should be doing this routinely anyway, because
|
|
you'll need to do it before your changes can eventually be submitted. Do this now and
|
|
solve any problems.
|
|
<blockquote>
|
|
<code>$ svn update</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>Check the status and save the output. Double check that no conflicts are showing.
|
|
<blockquote>
|
|
<code>$ svn status</code><br>
|
|
<br>
|
|
save a copy to reference later ...<br>
|
|
<br>
|
|
<code>$ svn status > saved-status.txt</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>Diff the sources and save the output.
|
|
<blockquote>
|
|
<code>$ svn diff > patch.txt</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>Clone a copy of the JMRI Git repository on your machine. (See the <a href=
|
|
"getgitcode.shtml">previous page</a> for detailed instructions.)
|
|
<blockquote>
|
|
<code>$ git clone https://github.com/JMRI/JMRI.git</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>In your new Git repo clone, checkout the sources as they were when the code was
|
|
switched from SVN to Git:
|
|
<blockquote>
|
|
<code>$ git checkout tags/svn-30001</code>
|
|
</blockquote>
|
|
This sets your working copy to be exactly the same as the last contents of SVN, the
|
|
same as the base for the <code>svn diff</code> you took earlier.<br>
|
|
</li>
|
|
|
|
<li>Apply the changes you had made in SVN to the new Git tree
|
|
<blockquote>
|
|
<code>$ patch -p0 < patch.txt</code>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>If you had created any completely new files in the SVN working directory, i.e. ones
|
|
with "A" or "?" status:
|
|
<ul>
|
|
<li>Copy those files into the corresponding place in your Git checkout.</li>
|
|
|
|
<li>
|
|
<em>Add</em> them to the Git staging queue: To <code>git add (pathname)</code> on
|
|
each of them to tell Git about them
|
|
<blockquote>
|
|
<code>$ git add <em>pathname/to/new/file</em></code>
|
|
</blockquote>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>Check the status to get a list of changes.
|
|
<blockquote>
|
|
<code>$ git status</code>
|
|
</blockquote>
|
|
You should see the same list of changed files as the "svn status" you ran
|
|
earlier.<br>
|
|
</li>
|
|
|
|
<li><code>git stash save</code>
|
|
</li>
|
|
|
|
<li><code>git checkout master</code>
|
|
</li>
|
|
|
|
<li><code>git stash pop</code><br>
|
|
<br>
|
|
Depending on how much progress has taken place in Git, this might show some conflicts.
|
|
If so, you have to resolve them here.</li>
|
|
</ol>
|
|
|
|
<p>Now you can start developing, without having lost anything.</p>
|
|
</dd>
|
|
|
|
<dt id="CVSCookies">Embedded CVS, RCS and SVN cookies</dt>
|
|
|
|
<dd>
|
|
<p>When JMRI was originally using CVS, we used lines like:<br>
|
|
<code># The next line is maintained by CVS, please don't change it<br>
|
|
# $Revision$</code><br>
|
|
as an additional way of tracking file versions. When we migrated to SVN, we kept those
|
|
lines in certain files, like decoder XML, properties files, etc, that users are likely to
|
|
edit and submit back for inclusion.</p>
|
|
|
|
<p>But with Git, there's less need for these. So we'll be removing these lines as time
|
|
allows. If you're working on a file and happen to see one, usually in the header, you can
|
|
just delete it (if it has somebody's name, you might want to add that to the copyright
|
|
notice if there is one.)</p>
|
|
</dd>
|
|
</dl>
|
|
<!--#include virtual="/help/en/parts/Footer.shtml" -->
|
|
</div>
|
|
<!-- closes #mainContent-->
|
|
</div>
|
|
<!-- closes #mBody-->
|
|
<!-- FAQ-Tail -->
|
|
<script type="text/javascript" src="https://www.jmri.org/web/js/faq.js"></script><!-- /FAQ-Tail -->
|
|
|
|
<script src="/js/help.js"></script>
|
|
</body>
|
|
</html>
|