From f4bb2308873d922900b6b3afb9c3dfaed943cd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Or=C5=A1uli=C4=87?= Date: Sat, 9 Sep 2017 19:59:45 +0200 Subject: [PATCH 1/2] Minor additions to commit descriptions Add the originating repo in the commit title. Amend the commit description with the original SHA. --- lib/Git/FastExport/Stitch.pm | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/Git/FastExport/Stitch.pm b/lib/Git/FastExport/Stitch.pm index e0ac569..793e116 100644 --- a/lib/Git/FastExport/Stitch.pm +++ b/lib/Git/FastExport/Stitch.pm @@ -90,9 +90,27 @@ sub stitch { # initiate the Git::FastExport stream my $stream = - $export->command(qw( fast-export --progress=1 --all --date-order )) + $export->command(split " ", "fast-export --all --date-order --export-marks=/tmp/marks-$name") ->stdout; + # Force fast-export to finish by dumping everything to memory. + # This ensures that the export-marks file is written, so we can read it. + my $dump_content = do { local $/; <$stream> }; + close($stream); + open($stream, '<', \$dump_content); + + my %mark_hashes; + open(FILE, "/tmp/marks-$name"); + while() { + chomp; + my @entry = split / /, $_; + $mark_hashes{substr($entry[0],1)} = $entry[1]; + } + $self->{repo}{$repo}{mark_hashes} = \%mark_hashes; + + close(FILE); + unlink("/tmp/marks-$name"); + # set up the internal structures $self->{repo}{$repo}{repo} = $repo; $self->{repo}{$repo}{dir} = $dir; @@ -162,6 +180,17 @@ sub next_block { # mark our original source $commit->{header} =~ s/$/-$repo->{name}/; + my @comment = split /\n/, $commit->{data}; + # Insert an additional blank line to separate the original ID if the commit + # has a description body. + if (@comment > 1) { push @comment, ""; } + $commit->{data} = join "\n", @comment; + + if ($repo->{name} ne "root") { + $commit->{data} = + "[$repo->{name}] " . $commit->{data} . "\nOriginal commit:\n" . + $repo->{mark_hashes}{$commit->{original_mark}}."\n"; + } # this commit's parents my @parents = map {/:(\d+)/g} @{ $commit->{from} || [] }, @@ -219,6 +248,7 @@ sub _translate_block { for ( @{ $block->{mark} || [] } ) { s/:(\d+)/:$self->{mark}/; $mark_map->{$repo}{$1} = $self->{mark}++; + $block->{original_mark} = $1; } # update marks in from & merge From c836b9f6dbbb7c6007aea0923224c36e819c3657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Or=C5=A1uli=C4=87?= Date: Mon, 11 Sep 2017 12:09:01 +0200 Subject: [PATCH 2/2] Add mirror update script. --- util/update_mirror.sh | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 util/update_mirror.sh diff --git a/util/update_mirror.sh b/util/update_mirror.sh new file mode 100755 index 0000000..d5ce072 --- /dev/null +++ b/util/update_mirror.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +# This script will pull all source repos every 300 seconds, and rebuild +# and push the resulting repo if there were any changes retrieved. +# Also, the master branch of the resulting repo is set to be the most +# recent branch of all the repository branches. Then, all non-master +# branches are deleted. + +# "root" is a special repository which is unmarked. Its files go to the +# root of the combined repository. It can be configured as a local +# repository (so it is not pulled). However, the script needs to be +# re-run if the root repository is only locally updated. + +SOURCE_REPOS="repo1 repo2 root:" +TARGET_REPO="repo_combined" + +# Whether to pull the root repository. +PULL_ROOT=false + +function update_repo() { + SOURCE=$(echo $1 | sed -E 's/:.*//') + cd $SOURCE + FIRST_RUN=$2 + + if [[ $FIRST_RUN = "true" ]]; then echo "First run: $FIRST_RUN."; fi + + OLD_HEAD=$(git rev-parse master) + #git remote update | grep -v "Fetching origin" + if [[ "$SOURCE" != "root" || "$PULL_ROOT" = "true" ]]; then + git pull origin master 2>&1 | grep -v -E "^From" | grep -v "FETCH_HEAD" | grep -v "Already up-to-date." + fi + NEW_HEAD=$(git rev-parse master) + cd .. + if [[ "$OLD_HEAD" != "$NEW_HEAD" || $FIRST_RUN = "true" ]]; then + if [[ "$OLD_HEAD" != "$NEW_HEAD" ]]; then + echo "Updated $SOURCE!" + echo "Old head: $OLD_HEAD" + echo "New head: $NEW_HEAD" + fi + cd "$TARGET_REPO" + (cd ..; git-stitch-repo $SOURCE_REPOS) | git fast-import --force --quiet + git update-ref -d refs/heads/master + BRANCHES_SORTED=$(git branch --sort=-committerdate | sed -E "s/[ *]+//g") + NEWEST_BRANCH=$(echo "$BRANCHES_SORTED" | head -n 1) + echo "Newest branch is $NEWEST_BRANCH" + ALL_BRANCHES=$(echo "$BRANCHES_SORTED" | tr '\n' ' ') + git update-ref refs/heads/master $NEWEST_BRANCH + git branch -D $ALL_BRANCHES + git push origin --force + cd .. + fi +} + + # First run, always stitches & pushes. + update_repo $(echo "$SOURCE_REPOS" | cut -f1 -d' ') true + +while true; do + date + for repo in $SOURCE_REPOS; do + update_repo $repo false + done + sleep 300 +done