Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion lib/Git/FastExport/Stitch.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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(<FILE>) {
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;
Expand Down Expand Up @@ -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} || [] },
Expand Down Expand Up @@ -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
Expand Down
63 changes: 63 additions & 0 deletions util/update_mirror.sh
Original file line number Diff line number Diff line change
@@ -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