summaryrefslogtreecommitdiff
path: root/contrib/fedora/utils/makerepo.sh
blob: 266aac8fe21885ce4e4ba8d6e4a7dc0e3f3f5adc (plain)
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
#!/bin/bash

#
# The script is ugly but is here to help to create a git-repository
# based on dist-git.
#
#  * Works with fedpkg and rhpkg
#  * Different packages are supported. See detect_build_type below.
#  * Creates first an initial commit of the source directory (after "fedpkg prep")
#  * Excludes files and creates a gitignore file. It does so by .git/makerepo.gitignore
#    which can be edited manually. Also, after a `$0 local`, it will record all files
#    with modifications to be ignored in the future.
#  * Revert each patch from the spec file
#  * Reapply each patch until you are where were originally (sans ignored files)
#  * Restore again the original state, i.e. replying the patches (including ignored
#    files -- that are no longer part of master-tip).
#  * Fetch from upstream origin (and add as remote)
#  * Fetch from a local git repository (and add as remote)
#  * It can detect the parent commit where the package branched of
#    and rebase the created history on top of that.
#  * optionally, do `fedpkg local`.
#
# ONE-TIME SETUP:
#   - clone the dist-git package
#       $ PACKAGE=libnl3
#       $ fedpkg clone $PACKAGE
#       $ cd $PACKAGE
#
#   - configure local git-repository (optional)
#       $ ln -s /path/to/local/clone .git/local
#
#   - create initial gitignore file (optional)
#       $ edit .git/makerepo.gitignore
#     or
#       $ edit .git/makerepo.gitignore.$BRANCHNAME
#
# USAGE:
#       $ cd $PACKAGE
#       $ makerepo.sh
#       $ makerepo.sh local
#


#set -vx

die() {
	echo "$@" >&2
	exit 1
}

containsElement () {
    local e
    local name="$1"
    shift
    local i=0

    for e in "${@:2}"; do
        if [[ "$e" == "$1" ]]; then
            eval "$name=$i"
            return 0;
        fi
        i=$((i+1))
    done
    return 1
}

git_remote_add_gnome() {
    git remote add "${2-origin}" "https://gitlab.gnome.org/GNOME/$1.git" && \
    git remote 'set-url' --push "${2-origin}" "git@gitlab.gnome.org:GNOME/$1.git"
}

git_remote_add_github() {
    git remote add "${2-origin}" "https://github.com/$1.git"
    git remote 'set-url' --push "${2-origin}" "git@github.com:$1.git"
}

srcdir="$(readlink -f "$(git rev-parse --show-toplevel 2>/dev/null)")"
[[ "x$srcdir" != x ]] || die "Could not detect dist-git directory (are you inside the git working directory?)"
cd "$srcdir" || die "Could not switch to dist-git directory"


if [[ "x$(ls -1d ./*.spec 2>/dev/null)" == x || ! -f "./sources" ]]; then
    die "**Error**: Directory "\`$srcdir\'" does not look like the dist-git pkg dir."
fi

if [[ "$FEDPKG" == "" ]]; then
    REMOTE="$(git config --get "branch.$(git branch --show-current).remote" 2>/dev/null)"
    URL="$(git config --get "remote.$REMOTE.url")"
    if [[ "$URL" = *'pkgs.devel.redhat.com'* ]]; then
        FEDPKG=rhpkg
    elif [[ "$URL" = *'gitlab.com'*'redhat/centos-stream'* ]]; then
        FEDPKG=centpkg
    elif [[ "$URL" = *'pkgs.fedoraproject.org/'* || "$URL" = *'src.fedoraproject.org/'* ]]; then
        FEDPKG=fedpkg
    else
        die "not inside dist-git repository? Check out a branch that has the dist-git remote tracking branch >>$PWD<<"
    fi
fi

split_patch() {
    # patches created with git-format-patch that contain more then one
    # commit, cannot be easily reverted with patch, because patch works
    # the patches from top down. In case of -R however, we have to apply
    # the latest patches first.

    read -r -d '' PERL_PROG <<-'EOF'
		use strict;
		use warnings;

		open FILE, $ARGV[0]  or die "Can't open $ARGV[0] for reading: $!\n";

		local $/ = undef;
		my $file = <FILE>;
		close FILE;

		my @patches = split(/\n\nFrom /,$file);

		my $i = $#patches + 1;
		my $patch;
		my $first = 1;
		foreach $patch (@patches){
			if ($first) {
				$first = 0;
			} else {
				$patch = "From $patch"
			}
			my $o = sprintf("%s%s%03d", $ARGV[0], $ARGV[1], $i);
			open(my $OUT, ">", $o) or die "Can't open $o for writing: $!";
			$i--;

			print $OUT "$patch";

			close $OUT;
		}
	EOF

    perl -e "$PERL_PROG" "$1" "$2"
}

spec_parse_patch_p() {
    local SPEC="$1"
    local NUM="$2"

    local P="$(sed -n "s/^%\<patch$NUM\>.* -p\([0-9]\+\) .*$/\1/p" "$SPEC")"

    echo "${P:-1}"
}

get_patch_origin() {
    local PATCH="$1"

    (
        cd "$srcdir"

        local HASH="$(git log -n1 --format="%H" HEAD -- "$PATCH")"

        if [[ "$HASH" == "" ]]; then
            return
        fi

        printf "\n\nPatch \"%s\" was last modified in commit:\n\n" "$PATCH"
        git log -n1 "$HASH" | sed 's/^[^ ]/    \0/'
    )
}

print_synopsis() {
    echo "SYNOPSIS: $(basename "$0") [--dist|-d DIST] [local|--local|-l] [-?|-h|--help|help] [NUM]"
    echo "  - If [NUM] is omitted, it will revert all patches from the spec file,"
    echo "    otherwise only the last NUM patches."
    echo "  - When specifying 'local', it will also call \`$FEDPKG local\` to configure"
    echo "    and build the output directory."
    echo "  - '--dist' implies '--local'. This argument is passed to ${FEDPKG}."
    echo "  TIP: symlink your local git clone of upstream to './.git/local'."
}

unset REVERT_COUNT
LOCAL=0
DIST=""
while [ $# -ne 0 ]; do
    ARG="$1"
    shift
    case "$ARG" in
        -h|'-?'|help|--help)
            print_synopsis
            exit 0
            ;;
        local|--local|-l)
            LOCAL=1
            ;;
        --dist|-d)
            DIST="$1"
            shift
            if [ "x$DIST" = x ]; then
                print_synopsis
                die "--dist needs an argument"
            fi
            ;;
        *)
            if [ -n "${REVERT_COUNT+x}" ]; then
                print_synopsis
                die "invalid argument \"$ARG\""
            fi
            case "$ARG" in
                ''|*[!0-9]*)
                    print_synopsis
                    die "invalid argument \"$ARG\": should be an integer (number of patches to revert)"
                    ;;
            esac
            REVERT_COUNT="$ARG"
            ;;
    esac
done

if [ "x$DIST" != x ]; then
    DIST=" --dist $DIST"
fi

# generate the clean dir
$FEDPKG $DIST prep || die "error while \`$FEDPKG$DIST prep\`"

detect_build_type() {
    local TEST_DIR="./$1/"
    local TEST_SPEC="$2"
    local TEST_BUILD_TYPE="$3"
    local DIRNAME

    if [[ -n "$BUILD_TYPE" || -z "$1" || "x$(ls -1d $TEST_DIR 2>/dev/null)" == x || ! -f "$TEST_SPEC" ]]; then
        return 1
    fi

    DIRNAME="$(ls -1d $TEST_DIR)" || die "could not find directory"
    DIRNAME="$(basename "$DIRNAME")"
    SPEC="$TEST_SPEC"

    if [[ -n "$TEST_BUILD_TYPE" ]]; then
        BUILD_TYPE="$TEST_BUILD_TYPE"
    else
        BUILD_TYPE="${TEST_SPEC%.spec}"
    fi
}

detect_dirname() {
    local BUILD_TYPE="$1"
    local DIRS=()
    local SOURCES
    local D suffix T

    SOURCES="$(sed 's/^\(SHA512 (\(.*\)) = [0-9a-f]\{128\}\|\([0-9a-f]\{32\} \+\(.*\)\)\)$/\2\4/' ./sources 2>/dev/null)"

    for suffix in .tar.gz .tar.bz .tar.xz .tgz .tar.bz2 ; do
        for T in ${SOURCES[@]}; do
            if [[ "$T" == *$suffix ]]; then
                D="${T%$suffix}"
                [[ -d "$D" ]] && DIRS=("${DIRS[@]}" "$D")
                D="$(tar -tf "$T" | sed 's#/.*##' | sort | uniq)"
                [[ -d "$D" ]] && DIRS=("${DIRS[@]}" "$D")
            fi
        done

        # iterate over all tarballs that start with "$BUILD_TYPE" and
        # see if there exists a directory with the same name as
        # the unpacked tarball (that is, stripping the suffix).
        for T in $(ls -1 "$BUILD_TYPE"*"$suffix" 2>/dev/null); do
            D="${T%$suffix}"
            [[ -d "$D" ]] && DIRS=("${DIRS[@]}" "$D")
        done
    done

    D=
    if [[ ${#DIRS[@]} -ge 1 ]]; then
        # return the newest directory.
        D="$(ls -1d --sort=time --time=ctime "${DIRS[@]}" 2>/dev/null | head -n1)"
    fi
    if [[ "$D" != "" ]]; then
        printf "%s" "$D"
        return 0
    fi
    return 1
}

BUILD_TYPE=
detect_build_type 'NetworkManager-[0-9]*' NetworkManager.spec
detect_build_type 'network-manager-applet-[0-9]*' network-manager-applet.spec
detect_build_type 'libnl-[0-9]*' libnl3.spec
detect_build_type 'NetworkManager-openvpn-[0-9]*' NetworkManager-openvpn.spec
detect_build_type 'NetworkManager-openswan-[0-9]*' NetworkManager-openswan.spec
detect_build_type 'NetworkManager-libreswan-[0-9]*' NetworkManager-libreswan.spec
detect_build_type 'NetworkManager-vpnc-[0-9]*' NetworkManager-vpnc.spec
detect_build_type 'ModemManager-[0-9]*' ModemManager.spec
detect_build_type 'wireless_tools.[0-9]*' wireless-tools.spec
detect_build_type 'umip-[0-9]*' mipv6-daemon.spec
detect_build_type 'initscripts-[0-9]*' initscripts.spec
detect_build_type 'libqmi-[0-9]*' libqmi.spec
detect_build_type 'libibverbs-[0-9]*' libibverbs.spec
detect_build_type 'iproute2-*' iproute.spec
detect_build_type 'glib-2*' glib2.spec
detect_build_type 'vpnc-*' vpnc.spec
detect_build_type 'gnome-control-center-*' control-center.spec gnome-control-center

if [[ -z "$BUILD_TYPE" ]]; then
    SPEC="$(ls -1 *.spec 2>/dev/null | head -n1)"
    BUILD_TYPE="${SPEC%.spec}"
    [[ -n "$BUILD_TYPE" ]] || die "Failed to detect repository type (no spec file)"

    [[ -f sources ]] || die "Failed to detect repository type (no sources file)"
fi

DIRNAME="$(detect_dirname "$BUILD_TYPE")" || die "Failed to detect repository type (no directory)."

CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
if [[ "x$CURRENT_BRANCH" != x && -f "./.git/makerepo.gitignore-$CURRENT_BRANCH" ]]; then
    MAKEREPO_GIT_IGNORE_MY="makerepo.gitignore-$CURRENT_BRANCH"
elif [[ -f ./.git/makerepo.gitignore ]]; then
    MAKEREPO_GIT_IGNORE_MY=makerepo.gitignore
else
    MAKEREPO_GIT_IGNORE_MY=""
fi
MAKEREPO_GIT_IGNORE_LAST="makerepo.gitignore.last-$CURRENT_BRANCH"

get_local_mirror() {
    local URL="$1"
    local DIRNAME
    local FULLNAME

    if [[ -z "$URL" ]]; then
        return
    fi

    [[ -n "$NO_REMOTE" ]] && return

    DIRNAME="${URL##*/}"
    DIRNAME="${DIRNAME%.git}"
    FULLNAME="$srcdir/.git/.makerepo-${DIRNAME}.git"

    if [ ! -d "$FULLNAME" ] && [ -d "$FULLNAME.git" ]; then
        # due to a bug, old versions of the script might have created "*.git.git/" directories.
        # rename.
        mv "$FULLNAME.git" "$FULLNAME"
    fi

    if [[ ! -d "$FULLNAME" ]]; then
        if [[ -f "$FULLNAME" ]]; then
            # create a file with name $FULLNAME, to suppress local mirroring
            return
        fi
        git clone --mirror --bare "$URL" "$FULLNAME/"
    fi
    (
        cd "$FULLNAME"
        git fetch origin --prune
        git gc
    )
    echo "$FULLNAME"
}

pushd "$DIRNAME"
    git init .
    # if you have a local clone of upstream, symlink it as ../.git/local.
    if [[ "$BUILD_TYPE" == "NetworkManager" ]]; then
        git remote add origin "https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git"
        git remote 'set-url' --push origin "git@gitlab.freedesktop.org:NetworkManager/NetworkManager.git"
        git config notes.displayRef refs/notes/bugs
        git config --add remote.origin.fetch refs/tags/*:refs/tags/*
        git config --add remote.origin.fetch refs/notes/bugs:refs/notes/bugs
    elif [[ "$BUILD_TYPE" == "ModemManager" ]]; then
        git remote add origin "git://anongit.freedesktop.org/ModemManager/ModemManager"
        git remote 'set-url' --push origin "ssh://$USER@git.freedesktop.org/git/ModemManager/ModemManager"
        git config --add remote.origin.fetch refs/tags/*:refs/tags/*
    elif [[ "$BUILD_TYPE" == "libnl3" ]]; then
        git_remote_add_github thom311/libnl
    elif [[ "$BUILD_TYPE" == "network-manager-applet" ||
            "$BUILD_TYPE" == "gnome-control-center" ||
            "$BUILD_TYPE" == "libnma" ||
            "$BUILD_TYPE" == "NetworkManager-fortisslvpn" ||
            "$BUILD_TYPE" == "NetworkManager-libreswan" ||
            "$BUILD_TYPE" == "NetworkManager-openconnect" ||
            "$BUILD_TYPE" == "NetworkManager-openvpn" ||
            "$BUILD_TYPE" == "NetworkManager-pptp" ||
            "$BUILD_TYPE" == "NetworkManager-vpnc" ]]; then
        git_remote_add_gnome "$BUILD_TYPE"
    elif [[ "$BUILD_TYPE" == "glib2" ]]; then
        git_remote_add_gnome glib
    elif [[ "$BUILD_TYPE" == "NetworkManager-openswan" ]]; then
        git remote add origin "git://git.gnome.org/network-manager-openswan";
        git remote 'set-url' --push origin "ssh://$USER@git.gnome.org/git/network-manager-openswan"
    elif [[ "$BUILD_TYPE" == "wpa_supplicant" ]]; then
        git remote add origin "git://w1.fi/hostap.git"
        git_remote_add_github NetworkManager/hostap nm
    elif [[ "$BUILD_TYPE" == "mipv6-daemon" ]]; then
        git remote add origin "git://git.umip.org/umip.git";
    elif [[ "$BUILD_TYPE" == "libqmi" ]]; then
        git remote add origin 'git://anongit.freedesktop.org/libqmi';
    elif [[ "$BUILD_TYPE" == "libibverbs" ]]; then
        git remote add origin 'git://git.kernel.org/pub/scm/libs/infiniband/libibverbs.git';
    elif [[ "$BUILD_TYPE" == "initscripts" ]]; then
        git remote add origin "https://git.fedorahosted.org/git/initscripts.git";
    elif [[ "$BUILD_TYPE" == "iproute" ]]; then
        git remote add origin "git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git"
    elif [[ "$BUILD_TYPE" == "dracut" ]]; then
        git remote add origin "https://github.com/dracutdevs/dracut.git"
    elif [[ "$BUILD_TYPE" == "systemd" ]]; then
        git remote add origin "https://github.com/systemd/systemd.git"
    elif [[ "$BUILD_TYPE" == "vpnc" ]]; then
        git_remote_add_github ndpgroup/vpnc
    elif [[ "$BUILD_TYPE" == "cloud-init" ]]; then
        git remote add origin "https://git.launchpad.net/cloud-init"
    elif [[ "$BUILD_TYPE" == "firewalld" ]]; then
        git remote add origin "https://github.com/firewalld/firewalld.git"
    elif [[ "$BUILD_TYPE" == "nftables" ]]; then
        git remote add origin "git://git.netfilter.org/nftables"
    elif [[ "$BUILD_TYPE" == "ulogd" ]]; then
        git remote add origin "https://git.netfilter.org/ulogd2"
    elif [[ "$BUILD_TYPE" == "libnetfilter_log" ]]; then
        git remote add origin "https://git.netfilter.org/$BUILD_TYPE"
    fi
    LOCAL_MIRROR_URL="$(LANG=C git remote -v | sed -n 's/^origin\t*\([^\t].*\) (fetch)/\1/p')"
    LOCAL_MIRROR="$(get_local_mirror "$LOCAL_MIRROR_URL")"
    if [[ -n "$LOCAL_MIRROR" ]]; then
        git remote add local-mirror "$LOCAL_MIRROR"
        git fetch local-mirror
    fi
    LOCAL_GIT="$(readlink -f ../.git/local/)"
    if [[ -d "$LOCAL_GIT" ]]; then
        git remote add local "$LOCAL_GIT/"
        git fetch local
    fi
    if [[ "$(git remote | grep '^origin$')x" != x && -z "$NO_REMOTE" ]]; then
        git fetch origin
        if [[ -n "$LOCAL_MIRROR" ]]; then
            git remote rm local-mirror
        fi
    fi
    git commit --allow-empty -m '*** empty initial commit'  # useful, to rebase the following commit
    git add -f -A .
    git commit -m '*** add all'
    git tag -f ALL
    ORIG_HEAD="`git rev-parse HEAD`"
    if [[ "x$RELEASE_BASE_COMMIT" == x ]]; then
        # if RELEASE_BASE_COMMIT is not set, try detecting the BASE_COMMIT...

        if [[ "$BUILD_TYPE" == "NetworkManager" ||
              "$BUILD_TYPE" == "NetworkManager-fortisslvpn" ||
              "$BUILD_TYPE" == "NetworkManager-libreswan" ||
              "$BUILD_TYPE" == "NetworkManager-pptp" ||
              "$BUILD_TYPE" == "NetworkManager-openconnect" ||
              "$BUILD_TYPE" == "NetworkManager-vpnc" ]]; then
            RELEASE_BASE_COMMIT="$(sed -n 's/^NM_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)"
        elif [[ "$BUILD_TYPE" == "libnl3" ]]; then
            RELEASE_BASE_COMMIT="$(sed -n 's/^LIBNL_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)"
            if [[ "$RELEASE_BASE_COMMIT" == "23c44dad998f72f39fd1fc24aa9579fd0a7f05c0" ]]; then
                RELEASE_BASE_COMMIT="e01b9df629e2f4f833fdc4fe0bda460bb738d136"
            fi
        elif [[ "$BUILD_TYPE" == "network-manager-applet" ||
                "$BUILD_TYPE" == "libnma" ]]; then
            RELEASE_BASE_COMMIT="$(sed -n 's/^NMA_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)"
            if [[ "$RELEASE_BASE_COMMIT" == "8d8e34f22d5fae476eda96cf36d828c3ae8b63d3" ]]; then
                RELEASE_BASE_COMMIT="a2377d7534780b96a32405cce2e5548e81bbd081"
            fi
        elif [[ "$BUILD_TYPE" == "glib2" ]]; then
            RELEASE_BASE_COMMIT="$(git rev-parse --verify -q "$(sed 's/.*\<glib-\([0-9]\+\.[0-9]\+\.[0-9]\+\)\.[a-z0-9_.]\+\>.*$/\1/' ../sources)^{commit}" 2>/dev/null)"
        elif [[ "$BUILD_TYPE" == "iproute" ]]; then
            RELEASE_BASE_COMMIT="$(git rev-parse --verify -q "$(sed 's/.*\<iproute2-\([0-9]\+\.[0-9]\+\.[0-9]\+\)\..*/v\1/' ../sources)^{commit}" 2>/dev/null)"
        elif [[ "$BUILD_TYPE" == "NetworkManager-openvpn" ]]; then
            RELEASE_BASE_COMMIT="$(sed -n 's/^NM_GIT_SHA=\(.*\)/\1/p' configure 2>/dev/null)"
            if [[ "x$RELEASE_BASE_COMMIT" == x ]]; then
                DATE="$(sed -n 's/%global snapshot .git\(20[0-3][0-9]\)\([0-1][0-9]\)\([0-3][0-9]\)/\1-\2-\3/p' "../$SPEC")"
                if [[ "x$DATE" != x ]]; then
                    RELEASE_BASE_COMMIT="$(git rev-list -n1 --date-order --before="$DATE" origin/master 2>/dev/null)"
                fi
            fi
        fi
        if [[ "x$RELEASE_BASE_COMMIT" == x ]]; then
            KNOWN_BASE_COMMITS="$(cat <<EOF
# NetworkManager
08670c9163a5d0f15c57c7891ef899eb125d9423  7251704430cb206f2c29bfebc45bd0fb *NetworkManager-0.9.9.0.git20131003.tar.bz2

# ModemManager
397761c9758c3a8c2d130afaf36dab645d6e0ecf  d9d93d2961ee35b4cd8a75a6a8631cb4  ModemManager-1.6.0.tar.xz
b23413a064f03fb2f2214fb32164bcb4b7037c45  67160b94c0eda90ebf95d1b620229ca1  ModemManager-1.6.10.tar.xz
526ec556bdf440fce3c48d3127836cf9d0b4501b  SHA512 (ModemManager-1.10.8.tar.xz) = c021939322be39e102371219e648d6acb3bc5b48cf570e02113ce559321155bfe5476b4012fd95f878c0a5c5d3b9d88fb19e95adec16a5b62a01581915a39f71

# libnl3
1a510c57e905c4beb06122b9688162c82d9b044f  d1111959652bd6ad87b2071f61c8c20c *libnl-doc-3.2.24.tar.gz
83c762d7cf6a6c54831e8d684b22804f497704c4  6fe7136558a9071e70673dcda38545b3 *libnl-3.2.21.tar.gz
c4d846f239036c05f516c1c71789e980b64b1e70  2e1c889494d274aca24ce5f6a748e66e *libnl-3.2.22.tar.gz
0446731124bea8c1b447cc52a5ad5ae5750810ff  636769646f5b81b0caead81eab151b45 *libnl-3.2.25-rc1.tar.gz
bd0e87b3d81d2498c3f35d5497771828bf04e017  e34999eaa184c84b315a8dff8afa4219  libnl-3.2.28-rc1.tar.gz
656f381ccf58785319bb0236595c896125d33ed0  bab12db1eb94a42129f712a44be91a67  libnl-3.2.28.tar.gz

# NetworkManager-applet
5d4f17e205f71972d4143f9760426a366b4129d7  9cc0e383c216d4bc31622a0cfb53aaa7 *network-manager-applet-0.9.9.0.git20140123.5d4f17e.tar.bz2
36c868498f09eacafcdce9d6b68ca5aeffaae899  3146f3ac3c30996a96cd2c602fbc81e1 *network-manager-applet-0.9.10.3.git20150511.36c8684.tar.bz2
2d5b36cf69ea6d5e11726d479012c8ad7d6fd9fc  7fc2ed3f0c46ed41ddabe99d51513b1c *network-manager-applet-1.0.4.tar.xz

# NetworkManager-libreswan, NetworkManager-openswan
64c90fd50e57854a3fff3784b92814ffa8159b05  6a373868f85ac3b7c953f7fd6c76e637 *NetworkManager-openswan-0.9.8.0.tar.xz
78555150e4df29eb39fa4a105f884f53b0f4523f  df9144805f37dc30dfaeab8da762f615 *NetworkManager-openswan-1.0.6.tar.xz
3ef831cf25e86675f9838bf58b1cd6e592c6e14f  01248eb95a1e1d647057a45aed85a3af *NetworkManager-libreswan-1.2.4.tar.xz

# NetworkManager-vpnc
89bdcd324f2e257eca59168a7d0be5608438aab0  abb26a6c3c8d6c1d91c78471aff86b3a *NetworkManager-vpnc-0.9.8.2.tar.xz
c37a79d43ebe1192ba8dcc5036cd668631b6473e  d87db7021629cef7c110a371dd42b7a8 *NetworkManager-vpnc-0.9.9.0.git20140131.tar.bz2
68ca41550f9289835ea9d80e1ee059322ebe749a  4c16379738264a117d09c171c645ff23 *NetworkManager-vpnc-1.2.2.tar.xz

# NetworkManager-openvpn
1f159f30617e4a3b8121074b8bf238312941370d  511eae0d4ac17c6d2659a3da2646296f *NetworkManager-openvpn-1.0.2.tar.xz
75585a94b394c04e45a28d2b032fe83dcdaeebee  ee4c09a8896eab3e1740f7c7bc1434f9  NetworkManager-openvpn-1.2.4.tar.xz

# mipv6-daemon
428974c2d0d8e75a2750a3ab0488708c5dfdd8e3  8e3ebd242e7926822bbdf5ce77c1d076 *mipv6-daemon-1.0.tar.gz

# libqmi
7d688f382f9756027bf92338e413e425365d2835  17d6c2b404ee1eb4d1e60050fef64491 *libqmi-1.6.0.tar.xz
49abf405f5e9f16542476dceeb20de6029edcf1c  SHA512 (libqmi-1.24.0.tar.xz) = e899765e67c1db0f758030e78b296015c476f938bb2afa01594b3e71a0b8d5fc2237c8272497aec891d5555523ecf0fecd69c4d0e14165c07072780621b3b502

# gnome-control-center
e87e0361b117f055ace2aa47cdddd0dc62a852f9  da949e268254af6aafdda0e8c1702384 *gnome-control-center-3.22.1.tar.xz

# wpa_supplicant
22760dd94722a61175ff90c59d88c4cda1ed5e23  3be2ebfdcced52e00eda0afe2889839d *wpa_supplicant-2.0.tar.gz

# libibverbs
990ca025d0ad967b6f266bae700bf82a4ceaff1a  1fe85889c8bbc4968b1feba6524ca408 *libibverbs-1.1.8.tar.gz

# initscripts
cc304f05edab6c408a0f061eb1a104f9f06b8587  86ef789876b65c61751ce854835b91d4  initscripts-9.49.35.tar.bz2

# dracut
00efe708cab023bfe6eaf530d8ac8ea97b440de2  SHA512 (dracut-050.tar.xz) = 9d9a66acfd6b9d2fd50855a59a2393e0602c2ef97119db046f68d6167ea84d1423fa465b8b4d96339febb38d5a96df26dec7862c4b3397c3d726db18d280eee4

# systemd
903dd65b5eb63257393955cb79777beb8c71afc1  SHA512 (systemd-253-rc1.tar.gz) = aaf0a6bf21bbc50a42015c9cb17f69d1aaf6cab6cabfba5140a94212fb864e38d638dace9a70447f62b4d2a817a0d3bd6f4ae8d9b3c2e741cdeb1cb332f70b65

# libnetfilter_log
97866a0a7482ca518bad39536c7c667bfb9604b2  2a4bb0654ae675a52d2e8d1c06090b94  libnetfilter_log-1.0.1.tar.bz2
b0e4be94c0b8f68d4e912402b93a130063c34e17  SHA512 (libnetfilter_log-1.0.2.tar.bz2) = 6b33718b1dd7f4504bceae14001da3a652cec46a6725a5dee83a7b55028cfa8e768cba917f968a5d5b60fd9ff04edf6040ef271a68e5fb65858bf73f4f9ccf23

# ulogd
79aa980f2df9dda0c097e8f883a62f414b9e5138  SHA512 (ulogd-2.0.8.tar.bz2) = 9f99f6f35bad5da4559d788dc3ba3dae17d4ae972737cae3313ecf68f08eaf5f55514fce6f30503437e4158fd30a06438b9249d5d20f6343964cbf690f87309d
EOF
)"
            OLDIFS="$IFS"
            IFS=$'\n'
            for KNOWN_BASE_COMMIT in $KNOWN_BASE_COMMITS; do
                MATCH="$(echo "$KNOWN_BASE_COMMIT" | sed -n 's/^[0-9a-f]\{40\} \+\(.*\)$/\1/p')"
                if [[ "x$MATCH" == x ]]; then
                    continue
                fi
                if grep -q "$MATCH" ../sources; then
                    RELEASE_BASE_COMMIT="$(echo "$KNOWN_BASE_COMMIT" | awk '{print $1}')"
                    break
                fi
            done
            IFS="$OLDIFS"
        fi
    fi
    if [[ x != "x$RELEASE_BASE_COMMIT" ]]; then
        if [[ "$RELEASE_BASE_COMMIT" == "-" ]]; then
            # you can disable detection of the RELEASE_BASE_COMMIT by setting it to '-'
            RELEASE_BASE_COMMIT=
        else
            # verify the base commit...
            RELEASE_BASE_COMMIT2="$(git rev-parse --verify -q "$RELEASE_BASE_COMMIT^{commit}" 2>/dev/null)"
            [[ x == "x$RELEASE_BASE_COMMIT2" ]] && test -z "$NO_REMOTE" && die "error detecting RELEASE_BASE_COMMIT=$RELEASE_BASE_COMMIT"
            RELEASE_BASE_COMMIT="$RELEASE_BASE_COMMIT2"
        fi
    fi
    if [[ x != "x$RELEASE_BASE_COMMIT" ]]; then
        git checkout -B master "$RELEASE_BASE_COMMIT" || die "could not checkout master"
        git tag -f BASE
        git rm --cached -r :/
        git checkout "$ORIG_HEAD" -- :/
        git clean -fdx :/
        git commit -m '*** add all'
        git tag -f ALL
        [[ x == "x$(git diff HEAD "$ORIG_HEAD")" ]] || die "error recreating initial tarball"
    fi
    (
        if [[ -n "$MAKEREPO_GIT_IGNORE_MY" ]]; then
            cat "../.git/$MAKEREPO_GIT_IGNORE_MY"
        fi
        if [[ -f "../.git/$MAKEREPO_GIT_IGNORE_LAST" ]]; then
            cat "../.git/$MAKEREPO_GIT_IGNORE_LAST"
        fi
        sed -n 's/^%patch\([0-9]\+\) \+.*-b \+\([^ ]\+\).*$/*\2/p' ../"$SPEC";
        echo '*.[0-9][0-9][0-9][0-9][-.]*.orig'
    ) | LANG=C sort | LANG=C uniq > .gitignore

    git rm --cached -r .
    git add --all .
    git commit -m "*** clean state (ignored files removed)"
    git tag -f CLEAN

    if [[ "$REVERT_COUNT" == "" || $REVERT_COUNT -gt 0 ]]; then

        # parse the list of patches
        IFS=$'\n' read -rd '' -a PATCH_LIST <<<"$(sed -n 's/^Patch\([0-9]\+\):[ 	]\+\(.*\)$/\1 \2/p' ../"$SPEC" | sort -n)"

        if [[ "$BUILD_TYPE" == "NetworkManager" ]]; then
            if containsElement idx "123 rh1085015-applet-translations.patch" "${PATCH_LIST[@]}"; then
                # for rhel-6, NetworkManager contains some patches that break the script. In this
                # case, truncate the list of what we would normally revert.
                PATCH_LIST=("${PATCH_LIST[@]:$((idx+1))}")
            fi
        fi

        # truncate the list of patches to revert/reapply
        if [[ "$REVERT_COUNT" == "" || "$REVERT_COUNT" -gt ${#PATCH_LIST[@]} ]]; then
            echo "revert all ${#PATCH_LIST[@]} patches"
        else
            echo "revert the last $REVERT_COUNT patches of ${#PATCH_LIST[@]}"
            PATCH_LIST=("${PATCH_LIST[@]:$((${#PATCH_LIST[@]} - $REVERT_COUNT))}")
        fi

        # split the list in index and patch file name
        PATCH_LIST_N=()
        for i in ${!PATCH_LIST[@]}; do
            LAST_PATCH_N[$i]=$(echo "${PATCH_LIST[$i]}" | sed -n 's/^\([0-9]\+\) \+.*$/\1/p')
            LAST_PATCH[$i]=$(  echo "${PATCH_LIST[$i]}" | sed -n 's/^\([0-9]\+\) \+\(.*\)$/\2/p')
        done

        # revert and patches in reverse order...
        BASECOMMIT=("`git rev-parse HEAD`")
        for j in "${!PATCH_LIST[@]}"; do
            i=$((${#PATCH_LIST[@]} - $j - 1))
            echo "revert Patch${LAST_PATCH_N[$i]} \"${LAST_PATCH[$i]}\"..."
            PNUM="$(spec_parse_patch_p "../$SPEC" "${LAST_PATCH_N[$i]}")"
            patch -f --no-backup-if-mismatch -R "-p$PNUM" < "../${LAST_PATCH[$i]}" || (
                # error applying patch. Maybe we have a multi line patch...

                rm -f "../${LAST_PATCH[$i]}".makerepo-split.*
                split_patch "../${LAST_PATCH[$i]}" ".makerepo-split."

                git reset --hard
                git clean -fdx
                for p in "../${LAST_PATCH[$i]}".makerepo-split.*; do
                    echo ">>> try split part $p for ${LAST_PATCH[$i]}"
                    patch --no-backup-if-mismatch -R "-p$PNUM" < "$p" || die "error reverting Patch${LAST_PATCH_N[$i]} ${LAST_PATCH[$i]}"
                done
            )
            git add --all .
            git commit --allow-empty -a -m "<< revert Patch${LAST_PATCH_N[$i]} \"${LAST_PATCH[$i]}\"$(get_patch_origin "${LAST_PATCH[$i]}")"
            BASECOMMIT=("`git rev-parse HEAD`" "${BASECOMMIT[@]}")
            git tag -f REVERT"${LAST_PATCH_N[$i]}"
        done

        # reapply the patches
        for i in ${!PATCH_LIST[@]}; do
            echo "reapply Patch${LAST_PATCH_N[$i]} \"${LAST_PATCH[$i]}\"..."

            # create an empty commit, indicating the commit before starting to reapply
            BASECOMMIT_REVERT="${BASECOMMIT[$((i))]}"
            COMMIT_MSG="$(git log -n1 --format='%s%n%n%b' "$BASECOMMIT_REVERT" | sed '1s/<< revert \(Patch.*"\)$/-- before reapplying \1/')"
            git commit --allow-empty -m "$COMMIT_MSG"
            git tag -f "BEFORE_PATCH${LAST_PATCH_N[$i]}"
            git tag -f "LAST0"

            # first try git-am to preserve the commit message, otherwise just revert the last commit
            if git am "../${LAST_PATCH[$i]}"; then
                # The tree to the version before should be identical after reapplying the patch.
                # Just to be sure, reset the commit.
                git reset "${BASECOMMIT[$((i+1))]}" -- .
                COMMIT_MSG="$(git log -n1 --format='%s%n%n%b' "$BASECOMMIT_REVERT" | sed '1s/<< revert \(Patch.*"\)$/-- after reapplying \1\n\ngit-am did not fully restore the previous state/')"
                git commit -m "$COMMIT_MSG" || echo "NOTHING TO COMMIT"
            else
                git am --abort
                git reset "${BASECOMMIT[$((i+1))]}" -- .
                COMMIT_MSG="$(git log -n1 --format='%s%n%n%b' "$BASECOMMIT_REVERT" | sed '1s/<< revert \(Patch.*"\)$/>> reapply \1/')"
                git commit --allow-empty -m "$COMMIT_MSG"
            fi
            git reset --hard HEAD
            git clean -fdx
            [[ x = "x$(git diff "${BASECOMMIT[$((i+1))]}" HEAD)" ]] || die "error reverting patch"
            git tag -f PATCH"${LAST_PATCH_N[$i]}"
        done
        git tag -f LAST
    fi
    git checkout "$ORIG_HEAD" -- .
    git checkout HEAD~ -- .gitignore
    git reset

    git gc
popd

if [[ $LOCAL != 0 ]]; then
    rm -rf ./.makerepo.git/
    mv "$DIRNAME/.git" ./.makerepo.git/
    $FEDPKG $DIST local -- --noclean
    mv ./.makerepo.git/ "$DIRNAME/.git"
    pushd "$DIRNAME"
        git checkout -- .gitignore

        # write git-ignore file...
        git status --porcelain | sed 's/^...//' >> "../.git/$MAKEREPO_GIT_IGNORE_LAST"
    popd
fi

echo SUCCESS;