/
GitFAQ.shtml
1146 lines (969 loc) · 46.6 KB
/
GitFAQ.shtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta name="generator" content=
"HTML Tidy for Mac OS X (vers 31 October 2006 - Apple Inc. build 15.17), see www.w3.org">
<title>JMRI: Git FAQ</title>
<meta name="author" content="Bob Jacobsen">
<meta name="keywords" content="JMRI technical code Git FAQ">
<!-- Style -->
<meta http-equiv="content-type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="/css/default.css"
media="screen">
<link rel="stylesheet" type="text/css" href="/css/print.css"
media="print">
<link rel="icon" href="/images/jmri.ico" type="image/png">
<link rel="home" title="Home" href="/">
<!-- /Style -->
<!-- FAQ-Head -->
<script type="text/javascript">
/*<![CDATA[*/document.documentElement.className="hasJS";/*]]>*/
</script>
<link rel="stylesheet" type="text/css" href="/web/css/faq.css"
media="screen">
<!-- /FAQ-Head -->
</head>
<body>
<!--#include virtual="/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>
<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=
"http://git-scm.com/downloads">Git download
page</a>.</li>
<li>It comes with the GitHub Desktop application,
available from the <a href=
"https://desktop.github.com">Git desktop download
page</a> (OS X and Windows only).</li>
<li>On the Mac, it's included when you <a href=
"https://developer.apple.com/xcode/download/">install
Xcode</a>.</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):
<a href="/web/images/GitHubWorkflow.png">
<img src="/web/images/GitHubWorkflow.png" align="right" height="25%" width="25%">
</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>
<pre style="font-family: monospace;">
$ git remote set-url --push origin https://github.com/<em>username</em>/JMRI.git
</pre>
where <code>username</code> is your github
user name. You can check the current status with of the
push and pull repositories with:
<pre style="font-family: monospace;">
$ git remote -v
origin https://github.com/JMRI/JMRI.git (fetch)
origin https://github.com/<em>username</em>/JMRI.git (push)
</pre>
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.
<p>Once you have a copy of your changes on GitHub, it is
easy to <a href=
"https://help.github.com/articles/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=
"/web/images/GitHubPR1.png">, 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 <i>clone</i> 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>
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.
<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>
<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>
<p>or</p>
<pre style="font-family: monospace;">
$ git pull https://github.com/JMRI/JMRI.git<br>
</pre>
</li>
<li>Make your changes locally, test them, etc.
<pre style="font-family: monospace;">
$ git add <i>newfile</i>
$ git rm <i>oldfile</i>
$ git add .
$ git status
$ git fetch
$ git merge
</pre>
</li>
<li>Make your changes available to the community
<pre style="font-family: monospace;">
$ git commit -m <i>"commit message"</i> <i>filename</i>, <i>filename</i>
</pre>
<p>or</p>
<pre style="font-family: monospace;">
$ git commit -a -m <i>"commit message"</i>
</pre>
</li>
</ul>
<h4>Using GitHub Desktop application</h4>
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>
For more on GitHub Desktop,
please see our
<a href="githubdesktopinto.shtml">page on using GitHub Desktop</a>.
<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" width="267" height=
"184" 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" width="260" height=
"98" 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" width="410" height="256"
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"
width="456" height="79" 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 syncing 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" width="154" height=
"122" 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" width="456" height=
"79" 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" width="129" height=
"215" 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" width="129"
height="215" 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" align="right">
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.
<ul>
<li>Somebody created a new branch (the colored line)
<li>That person made a change on their new branch (colored dot)
<li>And then, through the PR process, that was merged back onto
the master branch (rightmost black dot).
</ul>
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>
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" align="right">
<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>
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>
Later, he decides to merge his work back onto master
via the blue arrow in the middle.
<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>
By doing your work on your own branch:
<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>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.
</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.
<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" width="208" height="122"
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" width="156" height=
"79" 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://help.github.com/articles/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 https://github.com/arnie/JMRI.git arnie
git fetch arnie arnie-great-tool
git checkout arnie-great-tool
</pre>
where the 1st 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:
<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" width="410" height="255"
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" width="212" height="184"
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" width="212" height="184"
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://travis-ci.org">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">NetBeans JMRI
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 <b>not</b> 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" width="226" height="219"
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" align="right" width="392"
height="104" 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" width="446" height=
"114" alt="GitHub Web branch screen"></a>
</li>
<li>Next, pull that branch onto your own machine with
the command:
<pre style="font-family: monospace;">
git fetch https://github.com/<u>user</u>/JMRI.git <u>branch</u>:<u>local-branch</u>
</pre>
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 who's 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:
<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>
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>
Test that code:
<pre style="font-family: monospace;">
ant clean tests
</pre>
(and whatever you need to recreate). One 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
<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://guides.github.com/features/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 it's
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.