rpatch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,722 @@
1
+ #!/bin/sh
2
+ #
3
+ # Copyright (c) 2005 Junio C Hamano
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see http://www.gnu.org/licenses/ .
17
+
18
+ # The semantics of the editor variables are that of invoking
19
+ # sh -c "$EDITOR \"$@\"" files ...
20
+ #
21
+ # If our trash directory contains shell metacharacters, they will be
22
+ # interpreted if we just set $EDITOR directly, so do a little dance with
23
+ # environment variables to work around this.
24
+ #
25
+ # In particular, quoting isn't enough, as the path may contain the same quote
26
+ # that we're using.
27
+ test_set_editor () {
28
+ FAKE_EDITOR="$1"
29
+ export FAKE_EDITOR
30
+ EDITOR='"$FAKE_EDITOR"'
31
+ export EDITOR
32
+ }
33
+
34
+ test_decode_color () {
35
+ awk '
36
+ function name(n) {
37
+ if (n == 0) return "RESET";
38
+ if (n == 1) return "BOLD";
39
+ if (n == 30) return "BLACK";
40
+ if (n == 31) return "RED";
41
+ if (n == 32) return "GREEN";
42
+ if (n == 33) return "YELLOW";
43
+ if (n == 34) return "BLUE";
44
+ if (n == 35) return "MAGENTA";
45
+ if (n == 36) return "CYAN";
46
+ if (n == 37) return "WHITE";
47
+ if (n == 40) return "BLACK";
48
+ if (n == 41) return "BRED";
49
+ if (n == 42) return "BGREEN";
50
+ if (n == 43) return "BYELLOW";
51
+ if (n == 44) return "BBLUE";
52
+ if (n == 45) return "BMAGENTA";
53
+ if (n == 46) return "BCYAN";
54
+ if (n == 47) return "BWHITE";
55
+ }
56
+ {
57
+ while (match($0, /\033\[[0-9;]*m/) != 0) {
58
+ printf "%s<", substr($0, 1, RSTART-1);
59
+ codes = substr($0, RSTART+2, RLENGTH-3);
60
+ if (length(codes) == 0)
61
+ printf "%s", name(0)
62
+ else {
63
+ n = split(codes, ary, ";");
64
+ sep = "";
65
+ for (i = 1; i <= n; i++) {
66
+ printf "%s%s", sep, name(ary[i]);
67
+ sep = ";"
68
+ }
69
+ }
70
+ printf ">";
71
+ $0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1);
72
+ }
73
+ print
74
+ }
75
+ '
76
+ }
77
+
78
+ nul_to_q () {
79
+ "$PERL_PATH" -pe 'y/\000/Q/'
80
+ }
81
+
82
+ q_to_nul () {
83
+ "$PERL_PATH" -pe 'y/Q/\000/'
84
+ }
85
+
86
+ q_to_cr () {
87
+ tr Q '\015'
88
+ }
89
+
90
+ q_to_tab () {
91
+ tr Q '\011'
92
+ }
93
+
94
+ qz_to_tab_space () {
95
+ tr QZ '\011\040'
96
+ }
97
+
98
+ append_cr () {
99
+ sed -e 's/$/Q/' | tr Q '\015'
100
+ }
101
+
102
+ remove_cr () {
103
+ tr '\015' Q | sed -e 's/Q$//'
104
+ }
105
+
106
+ # In some bourne shell implementations, the "unset" builtin returns
107
+ # nonzero status when a variable to be unset was not set in the first
108
+ # place.
109
+ #
110
+ # Use sane_unset when that should not be considered an error.
111
+
112
+ sane_unset () {
113
+ unset "$@"
114
+ return 0
115
+ }
116
+
117
+ test_tick () {
118
+ if test -z "${test_tick+set}"
119
+ then
120
+ test_tick=1112911993
121
+ else
122
+ test_tick=$(($test_tick + 60))
123
+ fi
124
+ GIT_COMMITTER_DATE="$test_tick -0700"
125
+ GIT_AUTHOR_DATE="$test_tick -0700"
126
+ export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
127
+ }
128
+
129
+ # Stop execution and start a shell. This is useful for debugging tests and
130
+ # only makes sense together with "-v".
131
+ #
132
+ # Be sure to remove all invocations of this command before submitting.
133
+
134
+ test_pause () {
135
+ if test "$verbose" = t; then
136
+ "$SHELL_PATH" <&6 >&3 2>&4
137
+ else
138
+ error >&5 "test_pause requires --verbose"
139
+ fi
140
+ }
141
+
142
+ # Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]"
143
+ #
144
+ # This will commit a file with the given contents and the given commit
145
+ # message, and tag the resulting commit with the given tag name.
146
+ #
147
+ # <file>, <contents>, and <tag> all default to <message>.
148
+
149
+ test_commit () {
150
+ notick= &&
151
+ signoff= &&
152
+ while test $# != 0
153
+ do
154
+ case "$1" in
155
+ --notick)
156
+ notick=yes
157
+ ;;
158
+ --signoff)
159
+ signoff="$1"
160
+ ;;
161
+ *)
162
+ break
163
+ ;;
164
+ esac
165
+ shift
166
+ done &&
167
+ file=${2:-"$1.t"} &&
168
+ echo "${3-$1}" > "$file" &&
169
+ git add "$file" &&
170
+ if test -z "$notick"
171
+ then
172
+ test_tick
173
+ fi &&
174
+ git commit $signoff -m "$1" &&
175
+ git tag "${4:-$1}"
176
+ }
177
+
178
+ # Call test_merge with the arguments "<message> <commit>", where <commit>
179
+ # can be a tag pointing to the commit-to-merge.
180
+
181
+ test_merge () {
182
+ test_tick &&
183
+ git merge -m "$1" "$2" &&
184
+ git tag "$1"
185
+ }
186
+
187
+ # This function helps systems where core.filemode=false is set.
188
+ # Use it instead of plain 'chmod +x' to set or unset the executable bit
189
+ # of a file in the working directory and add it to the index.
190
+
191
+ test_chmod () {
192
+ chmod "$@" &&
193
+ git update-index --add "--chmod=$@"
194
+ }
195
+
196
+ # Unset a configuration variable, but don't fail if it doesn't exist.
197
+ test_unconfig () {
198
+ git config --unset-all "$@"
199
+ config_status=$?
200
+ case "$config_status" in
201
+ 5) # ok, nothing to unset
202
+ config_status=0
203
+ ;;
204
+ esac
205
+ return $config_status
206
+ }
207
+
208
+ # Set git config, automatically unsetting it after the test is over.
209
+ test_config () {
210
+ test_when_finished "test_unconfig '$1'" &&
211
+ git config "$@"
212
+ }
213
+
214
+ test_config_global () {
215
+ test_when_finished "test_unconfig --global '$1'" &&
216
+ git config --global "$@"
217
+ }
218
+
219
+ write_script () {
220
+ {
221
+ echo "#!${2-"$SHELL_PATH"}" &&
222
+ cat
223
+ } >"$1" &&
224
+ chmod +x "$1"
225
+ }
226
+
227
+ # Use test_set_prereq to tell that a particular prerequisite is available.
228
+ # The prerequisite can later be checked for in two ways:
229
+ #
230
+ # - Explicitly using test_have_prereq.
231
+ #
232
+ # - Implicitly by specifying the prerequisite tag in the calls to
233
+ # test_expect_{success,failure,code}.
234
+ #
235
+ # The single parameter is the prerequisite tag (a simple word, in all
236
+ # capital letters by convention).
237
+
238
+ test_set_prereq () {
239
+ satisfied_prereq="$satisfied_prereq$1 "
240
+ }
241
+ satisfied_prereq=" "
242
+ lazily_testable_prereq= lazily_tested_prereq=
243
+
244
+ # Usage: test_lazy_prereq PREREQ 'script'
245
+ test_lazy_prereq () {
246
+ lazily_testable_prereq="$lazily_testable_prereq$1 "
247
+ eval test_prereq_lazily_$1=\$2
248
+ }
249
+
250
+ test_run_lazy_prereq_ () {
251
+ script='
252
+ mkdir -p "$TRASH_DIRECTORY/prereq-test-dir" &&
253
+ (
254
+ cd "$TRASH_DIRECTORY/prereq-test-dir" &&'"$2"'
255
+ )'
256
+ say >&3 "checking prerequisite: $1"
257
+ say >&3 "$script"
258
+ test_eval_ "$script"
259
+ eval_ret=$?
260
+ rm -rf "$TRASH_DIRECTORY/prereq-test-dir"
261
+ if test "$eval_ret" = 0; then
262
+ say >&3 "prerequisite $1 ok"
263
+ else
264
+ say >&3 "prerequisite $1 not satisfied"
265
+ fi
266
+ return $eval_ret
267
+ }
268
+
269
+ test_have_prereq () {
270
+ # prerequisites can be concatenated with ','
271
+ save_IFS=$IFS
272
+ IFS=,
273
+ set -- $*
274
+ IFS=$save_IFS
275
+
276
+ total_prereq=0
277
+ ok_prereq=0
278
+ missing_prereq=
279
+
280
+ for prerequisite
281
+ do
282
+ case "$prerequisite" in
283
+ !*)
284
+ negative_prereq=t
285
+ prerequisite=${prerequisite#!}
286
+ ;;
287
+ *)
288
+ negative_prereq=
289
+ esac
290
+
291
+ case " $lazily_tested_prereq " in
292
+ *" $prerequisite "*)
293
+ ;;
294
+ *)
295
+ case " $lazily_testable_prereq " in
296
+ *" $prerequisite "*)
297
+ eval "script=\$test_prereq_lazily_$prerequisite" &&
298
+ if test_run_lazy_prereq_ "$prerequisite" "$script"
299
+ then
300
+ test_set_prereq $prerequisite
301
+ fi
302
+ lazily_tested_prereq="$lazily_tested_prereq$prerequisite "
303
+ esac
304
+ ;;
305
+ esac
306
+
307
+ total_prereq=$(($total_prereq + 1))
308
+ case "$satisfied_prereq" in
309
+ *" $prerequisite "*)
310
+ satisfied_this_prereq=t
311
+ ;;
312
+ *)
313
+ satisfied_this_prereq=
314
+ esac
315
+
316
+ case "$satisfied_this_prereq,$negative_prereq" in
317
+ t,|,t)
318
+ ok_prereq=$(($ok_prereq + 1))
319
+ ;;
320
+ *)
321
+ # Keep a list of missing prerequisites; restore
322
+ # the negative marker if necessary.
323
+ prerequisite=${negative_prereq:+!}$prerequisite
324
+ if test -z "$missing_prereq"
325
+ then
326
+ missing_prereq=$prerequisite
327
+ else
328
+ missing_prereq="$prerequisite,$missing_prereq"
329
+ fi
330
+ esac
331
+ done
332
+
333
+ test $total_prereq = $ok_prereq
334
+ }
335
+
336
+ test_declared_prereq () {
337
+ case ",$test_prereq," in
338
+ *,$1,*)
339
+ return 0
340
+ ;;
341
+ esac
342
+ return 1
343
+ }
344
+
345
+ test_expect_failure () {
346
+ test_start_
347
+ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
348
+ test "$#" = 2 ||
349
+ error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
350
+ export test_prereq
351
+ if ! test_skip "$@"
352
+ then
353
+ say >&3 "checking known breakage: $2"
354
+ if test_run_ "$2" expecting_failure
355
+ then
356
+ test_known_broken_ok_ "$1"
357
+ else
358
+ test_known_broken_failure_ "$1"
359
+ fi
360
+ fi
361
+ test_finish_
362
+ }
363
+
364
+ test_expect_success () {
365
+ test_start_
366
+ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
367
+ test "$#" = 2 ||
368
+ error "bug in the test script: not 2 or 3 parameters to test-expect-success"
369
+ export test_prereq
370
+ if ! test_skip "$@"
371
+ then
372
+ say >&3 "expecting success: $2"
373
+ if test_run_ "$2"
374
+ then
375
+ test_ok_ "$1"
376
+ else
377
+ test_failure_ "$@"
378
+ fi
379
+ fi
380
+ test_finish_
381
+ }
382
+
383
+ # test_external runs external test scripts that provide continuous
384
+ # test output about their progress, and succeeds/fails on
385
+ # zero/non-zero exit code. It outputs the test output on stdout even
386
+ # in non-verbose mode, and announces the external script with "# run
387
+ # <n>: ..." before running it. When providing relative paths, keep in
388
+ # mind that all scripts run in "trash directory".
389
+ # Usage: test_external description command arguments...
390
+ # Example: test_external 'Perl API' perl ../path/to/test.pl
391
+ test_external () {
392
+ test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
393
+ test "$#" = 3 ||
394
+ error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
395
+ descr="$1"
396
+ shift
397
+ export test_prereq
398
+ if ! test_skip "$descr" "$@"
399
+ then
400
+ # Announce the script to reduce confusion about the
401
+ # test output that follows.
402
+ say_color "" "# run $test_count: $descr ($*)"
403
+ # Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG
404
+ # to be able to use them in script
405
+ export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG
406
+ # Run command; redirect its stderr to &4 as in
407
+ # test_run_, but keep its stdout on our stdout even in
408
+ # non-verbose mode.
409
+ "$@" 2>&4
410
+ if [ "$?" = 0 ]
411
+ then
412
+ if test $test_external_has_tap -eq 0; then
413
+ test_ok_ "$descr"
414
+ else
415
+ say_color "" "# test_external test $descr was ok"
416
+ test_success=$(($test_success + 1))
417
+ fi
418
+ else
419
+ if test $test_external_has_tap -eq 0; then
420
+ test_failure_ "$descr" "$@"
421
+ else
422
+ say_color error "# test_external test $descr failed: $@"
423
+ test_failure=$(($test_failure + 1))
424
+ fi
425
+ fi
426
+ fi
427
+ }
428
+
429
+ # Like test_external, but in addition tests that the command generated
430
+ # no output on stderr.
431
+ test_external_without_stderr () {
432
+ # The temporary file has no (and must have no) security
433
+ # implications.
434
+ tmp=${TMPDIR:-/tmp}
435
+ stderr="$tmp/git-external-stderr.$$.tmp"
436
+ test_external "$@" 4> "$stderr"
437
+ [ -f "$stderr" ] || error "Internal error: $stderr disappeared."
438
+ descr="no stderr: $1"
439
+ shift
440
+ say >&3 "# expecting no stderr from previous command"
441
+ if [ ! -s "$stderr" ]; then
442
+ rm "$stderr"
443
+
444
+ if test $test_external_has_tap -eq 0; then
445
+ test_ok_ "$descr"
446
+ else
447
+ say_color "" "# test_external_without_stderr test $descr was ok"
448
+ test_success=$(($test_success + 1))
449
+ fi
450
+ else
451
+ if [ "$verbose" = t ]; then
452
+ output=`echo; echo "# Stderr is:"; cat "$stderr"`
453
+ else
454
+ output=
455
+ fi
456
+ # rm first in case test_failure exits.
457
+ rm "$stderr"
458
+ if test $test_external_has_tap -eq 0; then
459
+ test_failure_ "$descr" "$@" "$output"
460
+ else
461
+ say_color error "# test_external_without_stderr test $descr failed: $@: $output"
462
+ test_failure=$(($test_failure + 1))
463
+ fi
464
+ fi
465
+ }
466
+
467
+ # debugging-friendly alternatives to "test [-f|-d|-e]"
468
+ # The commands test the existence or non-existence of $1. $2 can be
469
+ # given to provide a more precise diagnosis.
470
+ test_path_is_file () {
471
+ if ! [ -f "$1" ]
472
+ then
473
+ echo "File $1 doesn't exist. $*"
474
+ false
475
+ fi
476
+ }
477
+
478
+ test_path_is_dir () {
479
+ if ! [ -d "$1" ]
480
+ then
481
+ echo "Directory $1 doesn't exist. $*"
482
+ false
483
+ fi
484
+ }
485
+
486
+ test_path_is_missing () {
487
+ if [ -e "$1" ]
488
+ then
489
+ echo "Path exists:"
490
+ ls -ld "$1"
491
+ if [ $# -ge 1 ]; then
492
+ echo "$*"
493
+ fi
494
+ false
495
+ fi
496
+ }
497
+
498
+ # test_line_count checks that a file has the number of lines it
499
+ # ought to. For example:
500
+ #
501
+ # test_expect_success 'produce exactly one line of output' '
502
+ # do something >output &&
503
+ # test_line_count = 1 output
504
+ # '
505
+ #
506
+ # is like "test $(wc -l <output) = 1" except that it passes the
507
+ # output through when the number of lines is wrong.
508
+
509
+ test_line_count () {
510
+ if test $# != 3
511
+ then
512
+ error "bug in the test script: not 3 parameters to test_line_count"
513
+ elif ! test $(wc -l <"$3") "$1" "$2"
514
+ then
515
+ echo "test_line_count: line count for $3 !$1 $2"
516
+ cat "$3"
517
+ return 1
518
+ fi
519
+ }
520
+
521
+ # This is not among top-level (test_expect_success | test_expect_failure)
522
+ # but is a prefix that can be used in the test script, like:
523
+ #
524
+ # test_expect_success 'complain and die' '
525
+ # do something &&
526
+ # do something else &&
527
+ # test_must_fail git checkout ../outerspace
528
+ # '
529
+ #
530
+ # Writing this as "! git checkout ../outerspace" is wrong, because
531
+ # the failure could be due to a segv. We want a controlled failure.
532
+
533
+ test_must_fail () {
534
+ "$@"
535
+ exit_code=$?
536
+ if test $exit_code = 0; then
537
+ echo >&2 "test_must_fail: command succeeded: $*"
538
+ return 1
539
+ elif test $exit_code -gt 129 -a $exit_code -le 192; then
540
+ echo >&2 "test_must_fail: died by signal: $*"
541
+ return 1
542
+ elif test $exit_code = 127; then
543
+ echo >&2 "test_must_fail: command not found: $*"
544
+ return 1
545
+ elif test $exit_code = 126; then
546
+ echo >&2 "test_must_fail: valgrind error: $*"
547
+ return 1
548
+ fi
549
+ return 0
550
+ }
551
+
552
+ # Similar to test_must_fail, but tolerates success, too. This is
553
+ # meant to be used in contexts like:
554
+ #
555
+ # test_expect_success 'some command works without configuration' '
556
+ # test_might_fail git config --unset all.configuration &&
557
+ # do something
558
+ # '
559
+ #
560
+ # Writing "git config --unset all.configuration || :" would be wrong,
561
+ # because we want to notice if it fails due to segv.
562
+
563
+ test_might_fail () {
564
+ "$@"
565
+ exit_code=$?
566
+ if test $exit_code -gt 129 -a $exit_code -le 192; then
567
+ echo >&2 "test_might_fail: died by signal: $*"
568
+ return 1
569
+ elif test $exit_code = 127; then
570
+ echo >&2 "test_might_fail: command not found: $*"
571
+ return 1
572
+ fi
573
+ return 0
574
+ }
575
+
576
+ # Similar to test_must_fail and test_might_fail, but check that a
577
+ # given command exited with a given exit code. Meant to be used as:
578
+ #
579
+ # test_expect_success 'Merge with d/f conflicts' '
580
+ # test_expect_code 1 git merge "merge msg" B master
581
+ # '
582
+
583
+ test_expect_code () {
584
+ want_code=$1
585
+ shift
586
+ "$@"
587
+ exit_code=$?
588
+ if test $exit_code = $want_code
589
+ then
590
+ return 0
591
+ fi
592
+
593
+ echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
594
+ return 1
595
+ }
596
+
597
+ # test_cmp is a helper function to compare actual and expected output.
598
+ # You can use it like:
599
+ #
600
+ # test_expect_success 'foo works' '
601
+ # echo expected >expected &&
602
+ # foo >actual &&
603
+ # test_cmp expected actual
604
+ # '
605
+ #
606
+ # This could be written as either "cmp" or "diff -u", but:
607
+ # - cmp's output is not nearly as easy to read as diff -u
608
+ # - not all diff versions understand "-u"
609
+
610
+ test_cmp() {
611
+ $GIT_TEST_CMP "$@"
612
+ }
613
+
614
+ # Check if the file expected to be empty is indeed empty, and barfs
615
+ # otherwise.
616
+
617
+ test_must_be_empty () {
618
+ if test -s "$1"
619
+ then
620
+ echo "'$1' is not empty, it contains:"
621
+ cat "$1"
622
+ return 1
623
+ fi
624
+ }
625
+
626
+ # Tests that its two parameters refer to the same revision
627
+ test_cmp_rev () {
628
+ git rev-parse --verify "$1" >expect.rev &&
629
+ git rev-parse --verify "$2" >actual.rev &&
630
+ test_cmp expect.rev actual.rev
631
+ }
632
+
633
+ # Print a sequence of numbers or letters in increasing order. This is
634
+ # similar to GNU seq(1), but the latter might not be available
635
+ # everywhere (and does not do letters). It may be used like:
636
+ #
637
+ # for i in `test_seq 100`; do
638
+ # for j in `test_seq 10 20`; do
639
+ # for k in `test_seq a z`; do
640
+ # echo $i-$j-$k
641
+ # done
642
+ # done
643
+ # done
644
+
645
+ test_seq () {
646
+ case $# in
647
+ 1) set 1 "$@" ;;
648
+ 2) ;;
649
+ *) error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
650
+ esac
651
+ "$PERL_PATH" -le 'print for $ARGV[0]..$ARGV[1]' -- "$@"
652
+ }
653
+
654
+ # This function can be used to schedule some commands to be run
655
+ # unconditionally at the end of the test to restore sanity:
656
+ #
657
+ # test_expect_success 'test core.capslock' '
658
+ # git config core.capslock true &&
659
+ # test_when_finished "git config --unset core.capslock" &&
660
+ # hello world
661
+ # '
662
+ #
663
+ # That would be roughly equivalent to
664
+ #
665
+ # test_expect_success 'test core.capslock' '
666
+ # git config core.capslock true &&
667
+ # hello world
668
+ # git config --unset core.capslock
669
+ # '
670
+ #
671
+ # except that the greeting and config --unset must both succeed for
672
+ # the test to pass.
673
+ #
674
+ # Note that under --immediate mode, no clean-up is done to help diagnose
675
+ # what went wrong.
676
+
677
+ test_when_finished () {
678
+ test_cleanup="{ $*
679
+ } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
680
+ }
681
+
682
+ # Most tests can use the created repository, but some may need to create more.
683
+ # Usage: test_create_repo <directory>
684
+ test_create_repo () {
685
+ test "$#" = 1 ||
686
+ error "bug in the test script: not 1 parameter to test-create-repo"
687
+ repo="$1"
688
+ mkdir -p "$repo"
689
+ (
690
+ cd "$repo" || error "Cannot setup test environment"
691
+ gistore init --repo . >&3 2>&4 ||
692
+ error "cannot run git init -- have you built things yet?"
693
+ ) || exit
694
+ }
695
+
696
+ # This function helps on symlink challenged file systems when it is not
697
+ # important that the file system entry is a symbolic link.
698
+ # Use test_ln_s_add instead of "ln -s x y && git add y" to add a
699
+ # symbolic link entry y to the index.
700
+
701
+ test_ln_s_add () {
702
+ if test_have_prereq SYMLINKS
703
+ then
704
+ ln -s "$1" "$2" &&
705
+ git update-index --add "$2"
706
+ else
707
+ printf '%s' "$1" >"$2" &&
708
+ ln_s_obj=$(git hash-object -w "$2") &&
709
+ git update-index --add --cacheinfo 120000 $ln_s_obj "$2"
710
+ fi
711
+ }
712
+
713
+ git_log_only_subject() {
714
+ repo=$1
715
+ shift
716
+ if test $(gistore check-git-version 1.6.3) -ge 0; then
717
+ gistore log --repo $repo --pretty="%s" $@
718
+ else
719
+ gistore log --repo $repo --pretty="format:%s" $@
720
+ printf "\n"
721
+ fi
722
+ }