зеркало из https://github.com/dotnet/fsharp.git
113 строки
4.8 KiB
Bash
Executable File
113 строки
4.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
|
|
|
# This script generates a patch by comparing the contents of the fsharp/fsharp
|
|
# and Microsoft/visualfsharp GitHub repositories. The resulting patch can be applied,
|
|
# if desired, to one of the repositories to synchronize changes in one direction;
|
|
# CAUTION MUST BE TAKEN though, since this script generates the patch in a way that
|
|
# ignores any ordering of commits in the repos -- so it could also end up reverting
|
|
# changes that were actually needed.
|
|
# The produced patch is primarily useful for examining differences between two repos
|
|
# and making it easier to submit targeted PRs to manually synchronize changes.
|
|
|
|
# Helper function to clean up after we're done (or if there's an error).
|
|
cleanup () {
|
|
# Leave the working directory, then delete it.
|
|
{ popd && rm -rf "$tmpdir"; } || printf "Unable to clean up temp directory '%s'\n" "$tmpdir"
|
|
}
|
|
|
|
# Helper function to print an error message and exit with a non-zero error code.
|
|
failwith () {
|
|
printf "Error: %s\n" "$1" >&2
|
|
cleanup
|
|
exit 1
|
|
}
|
|
|
|
# Delete the .git folder from a folder containing an extracted/cloned repository.
|
|
remove_git () {
|
|
{ pushd "$1" && rm -rf .git && popd; } || \
|
|
{ printf "Error: Couldn't remove .git from '%s'\n" "$1"; cleanup_error; }
|
|
}
|
|
|
|
# Delete "don't care" files from a folder containing an extracted/cloned repository.
|
|
# These are files with known differences between the two repos, but where we don't care
|
|
# about those differences for the purposes of generating a patch.
|
|
remove_irrelevant_files () {
|
|
if pushd "$1"; then
|
|
# TODO: Use 'for in _ do' syntax here instead? Maybe read the list from a separate text file?
|
|
# If any of the files in here can't be removed, ignore the failure and keep going.
|
|
rm .travis.yml
|
|
rm CHANGELOG.md
|
|
rm CONTRIBUTING.md
|
|
rm README.md
|
|
|
|
popd
|
|
fi
|
|
}
|
|
|
|
# Options for controlling the behavior of this script.
|
|
tmpdir="diff_tmp" # name of temp folder to create and work in
|
|
fetch_source_by_cloning=1 # git diff doesn't seem to like curl+tar, so clone with git for now.
|
|
github_org1="fsharp"
|
|
github_repo1="fsharp"
|
|
github_org2="Microsoft"
|
|
github_repo2="visualfsharp"
|
|
repo_dir1="${github_org1}_${github_repo1}"
|
|
repo_dir2="${github_org2}_${github_repo2}"
|
|
include_all_changes=0 # If set to 1, file additions/deletions will also be included in the patch.
|
|
patch_path="../${github_repo1}-${github_repo2}.patch"
|
|
|
|
# Create a temporary directory to work in.
|
|
if ! mkdir "$tmpdir"; then
|
|
printf "Unable to create temp directory '%s' (does it already exist?)\n" "$tmpdir"
|
|
exit 1
|
|
fi
|
|
|
|
# Enter the temporary directory.
|
|
if ! pushd "$tmpdir"; then
|
|
printf "Can't enter temp directory '%s'\n" "$tmpdir"
|
|
exit 1
|
|
fi
|
|
|
|
# We can either fetch the source from the target repos by cloning them,
|
|
# or simply by downloading an archive/tarball of the current 'master' branches.
|
|
if [ "$fetch_source_by_cloning" = '1' ]; then
|
|
# Clone folders with git.
|
|
# The code above using curl and tar should work, but git diff doesn't seem to like it.
|
|
{ git clone "https://github.com/${github_org1}/${github_repo1}.git" "$repo_dir1" && \
|
|
git clone "https://github.com/${github_org2}/${github_repo2}.git" "$repo_dir2"; } ||
|
|
{ printf "Unable to clone one or more of the target repositories.\n" && cleanup_error; }
|
|
|
|
# Enter each cloned repo and delete the .git folder to eliminate a bunch of garbage in the patch.
|
|
remove_git "$repo_dir1"
|
|
remove_git "$repo_dir2"
|
|
else
|
|
# Download source tarballs for both repos.
|
|
repo_archive1="$repo_dir1.zip"
|
|
repo_archive2="$repo_dir2.zip"
|
|
{ curl -L -o "$repo_archive1" "https://github.com/${github_org1}/${github_repo1}/archive/master.zip" && \
|
|
curl -L -o "$repo_archive2" "https://github.com/${github_org2}/${github_repo2}/archive/master.zip"; } || \
|
|
{ printf "Couldn't download one or more of the source tarballs.\n" && cleanup_error; }
|
|
|
|
# Extract the contents of the source tarballs.
|
|
{ mkdir "$repo_dir1" && tar -xzf "$repo_archive1" -C "$repo_dir1" && \
|
|
mkdir "$repo_dir2" && tar -xzf "$repo_archive2" -C "$repo_dir2"; } || \
|
|
{ printf "Couldn't extract one or more of the source tarballs.\n" && cleanup_error; }
|
|
fi
|
|
|
|
# Remove unwanted/"don't care" files from both repos.
|
|
remove_irrelevant_files "$repo_dir1"
|
|
remove_irrelevant_files "$repo_dir2"
|
|
|
|
# Use git-diff to compare the two source trees and create a patch.
|
|
# Note, the 'git diff' command returns with non-zero exit code if there are any warnings emitted,
|
|
# which there will be -- so we can't really check the exit code to see if it succeeded'
|
|
if [ "$include_all_changes" != '1' ]; then
|
|
diff_filter_arg="--diff-filter=ad"
|
|
fi
|
|
|
|
git diff --diff-algorithm=minimal "$diff_filter_arg" --no-index -- "$repo_dir1" "$repo_dir2" > "$patch_path"
|
|
|
|
# Cleanup the temp folder.
|
|
cleanup
|