mirror of
https://github.com/facebook/sapling.git
synced 2024-10-12 01:39:21 +03:00
mononoke: correct handling of non-pushrebase pushes in push redirector
Summary: One notable change - non-pushrebase pushes on shared bookmarks will now fail. Reviewed By: ikostia Differential Revision: D18425394 fbshipit-source-id: 4983789a15caa1ceec044d379e3a4748b2821dea
This commit is contained in:
parent
09d9a5bed9
commit
db61f6da5a
@ -32,6 +32,7 @@ use futures::Future;
|
||||
use futures_preview::compat::Future01CompatExt;
|
||||
use futures_preview::future::try_join_all;
|
||||
use futures_util::{future::FutureExt, try_future::TryFutureExt, try_join};
|
||||
use metaconfig_types::CommitSyncConfig;
|
||||
use mononoke_types::ChangesetId;
|
||||
use pushrebase::PushrebaseChangesetPair;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@ -52,6 +53,8 @@ pub struct RepoSyncTarget {
|
||||
pub large_to_small_commit_syncer: CommitSyncer<Arc<dyn SyncedCommitMapping>>,
|
||||
// A struct, needed to backsync commits
|
||||
pub target_repo_dbs: TargetRepoDbs,
|
||||
// Config for commit sync functionality
|
||||
pub commit_sync_config: CommitSyncConfig,
|
||||
}
|
||||
|
||||
impl RepoSyncTarget {
|
||||
@ -503,6 +506,17 @@ impl RepoSyncTarget {
|
||||
new: maybe_new,
|
||||
} = orig;
|
||||
|
||||
if self
|
||||
.commit_sync_config
|
||||
.common_pushrebase_bookmarks
|
||||
.contains(&name)
|
||||
{
|
||||
return Err(format_err!(
|
||||
"cannot force pushrebase to shared bookmark {}",
|
||||
name
|
||||
));
|
||||
}
|
||||
|
||||
let (old, new) = try_join!(
|
||||
async {
|
||||
match maybe_old {
|
||||
|
@ -195,6 +195,7 @@ fn create_repo_sync_target(
|
||||
small_to_large_commit_syncer,
|
||||
large_to_small_commit_syncer,
|
||||
target_repo_dbs,
|
||||
commit_sync_config,
|
||||
})
|
||||
.boxify()
|
||||
}
|
||||
|
214
tests/integration/test-push-redirector-pushrebase-onesided.t
Normal file
214
tests/integration/test-push-redirector-pushrebase-onesided.t
Normal file
@ -0,0 +1,214 @@
|
||||
$ . "${TEST_FIXTURES}/library.sh"
|
||||
|
||||
setup configuration
|
||||
$ REPOTYPE="blob:files"
|
||||
$ REPOID=0 REPONAME=large-mon setup_common_config $REPOTYPE
|
||||
$ REPOID=1 REPONAME=small-mon-1 setup_common_config $REPOTYPE
|
||||
$ REPOID=2 REPONAME=small-mon-2 setup_common_config $REPOTYPE
|
||||
$ cat >> "$TESTTMP/mononoke-config/common/commitsyncmap.toml" <<EOF
|
||||
> [megarepo_test]
|
||||
> large_repo_id = 0
|
||||
> common_pushrebase_bookmarks = ["master_bookmark"]
|
||||
> [[megarepo_test.small_repos]]
|
||||
> repoid = 1
|
||||
> bookmark_prefix = "bookprefix1/"
|
||||
> default_action = "prepend_prefix"
|
||||
> default_prefix = "smallrepofolder1"
|
||||
> direction = "large_to_small"
|
||||
> [megarepo_test.small_repos.map]
|
||||
> "special"="specialsmallrepofolder1"
|
||||
> [[megarepo_test.small_repos]]
|
||||
> repoid = 2
|
||||
> bookmark_prefix = "bookprefix2/"
|
||||
> default_action = "prepend_prefix"
|
||||
> default_prefix = "smallrepofolder2"
|
||||
> direction = "small_to_large"
|
||||
> [megarepo_test.small_repos.map]
|
||||
> "special"="specialsmallrepofolder2"
|
||||
> EOF
|
||||
|
||||
Verification function
|
||||
$ function verify_wc() {
|
||||
> local large_repo_commit
|
||||
> large_repo_commit="$1"
|
||||
> "$MONONOKE_ADMIN" "${CACHING_ARGS[@]}" --log-level ERROR --mononoke-config-path "$TESTTMP"/mononoke-config --source-repo-id="$REPOIDLARGE" --target-repo-id="$REPOIDSMALL1" crossrepo verify-wc $large_repo_commit
|
||||
> }
|
||||
|
||||
setup hg server repos
|
||||
$ function createfile { mkdir -p "$(dirname $1)" && echo "$1" > "$1" && hg add -q "$1"; }
|
||||
$ function create_first_post_move_commit {
|
||||
> echo 1 > "$1/filetoremove" && hg add "$1/filetoremove" && hg ci -m 'first post-move commit'
|
||||
> hg revert -r .^ "$1/filetoremove"
|
||||
> }
|
||||
|
||||
$ cd $TESTTMP
|
||||
$ hginit_treemanifest small-hg-srv-1
|
||||
$ hginit_treemanifest small-hg-srv-2
|
||||
$ cd "$TESTTMP/small-hg-srv-1"
|
||||
$ echo 1 > file.txt
|
||||
$ hg addremove -q && hg ci -q -m 'pre-move commit 1'
|
||||
$ cd "$TESTTMP/small-hg-srv-2"
|
||||
$ echo 2 > file.txt
|
||||
$ hg addremove -q && hg ci -q -m 'pre-move commit 2'
|
||||
|
||||
$ cd "$TESTTMP"
|
||||
$ cp -r small-hg-srv-1 large-hg-srv
|
||||
$ cd large-hg-srv
|
||||
$ mkdir smallrepofolder1
|
||||
$ hg mv file.txt smallrepofolder1/file.txt
|
||||
$ hg ci -m 'move commit'
|
||||
$ mkdir smallrepofolder2
|
||||
$ echo 2 > smallrepofolder2/file.txt
|
||||
$ hg addremove -q
|
||||
$ hg ci -m "move commit for repo 2"
|
||||
$ create_first_post_move_commit smallrepofolder1
|
||||
$ hg book -r . master_bookmark
|
||||
|
||||
$ cd "$TESTTMP/small-hg-srv-1"
|
||||
$ create_first_post_move_commit .
|
||||
$ hg book -r . master_bookmark
|
||||
|
||||
$ cd "$TESTTMP/small-hg-srv-2"
|
||||
$ hg book -r . master_bookmark
|
||||
|
||||
blobimport hg servers repos into Mononoke repos
|
||||
$ cd $TESTTMP
|
||||
$ REPOIDLARGE=0
|
||||
$ REPOIDSMALL1=1
|
||||
$ REPOIDSMALL2=2
|
||||
$ REPOID="$REPOIDLARGE" blobimport large-hg-srv/.hg large-mon
|
||||
$ REPOID="$REPOIDSMALL1" blobimport small-hg-srv-1/.hg small-mon-1
|
||||
$ REPOID="$REPOIDSMALL2" blobimport small-hg-srv-2/.hg small-mon-2
|
||||
|
||||
setup hg client repos
|
||||
$ function init_client() {
|
||||
> cd "$TESTTMP"
|
||||
> hgclone_treemanifest ssh://user@dummy/"$1" "$2" --noupdate --config extensions.remotenames=
|
||||
> cd "$TESTTMP/$2"
|
||||
> cat >> .hg/hgrc <<EOF
|
||||
> [extensions]
|
||||
> pushrebase =
|
||||
> remotenames =
|
||||
> EOF
|
||||
> }
|
||||
|
||||
$ init_client small-hg-srv-1 small-hg-client-1
|
||||
$ init_client small-hg-srv-2 small-hg-client-2
|
||||
$ cd "$TESTTMP"
|
||||
$ init_client large-hg-srv large-hg-client
|
||||
|
||||
Setup helpers
|
||||
$ log() {
|
||||
> hg log -G -T "{desc} [{phase};rev={rev};{node|short}] {remotenames}" "$@"
|
||||
> }
|
||||
|
||||
$ LARGE_MASTER_BONSAI=$(get_bonsai_bookmark $REPOIDLARGE master_bookmark)
|
||||
$ SMALL1_MASTER_BONSAI=$(get_bonsai_bookmark $REPOIDSMALL1 master_bookmark)
|
||||
$ SMALL2_MASTER_BONSAI=$(get_bonsai_bookmark $REPOIDSMALL2 master_bookmark)
|
||||
|
||||
start mononoke server
|
||||
$ mononoke
|
||||
$ wait_for_mononoke
|
||||
|
||||
Make sure mapping is set up and we know what we don't have to sync initial entries
|
||||
$ add_synced_commit_mapping_entry $REPOIDSMALL1 $SMALL1_MASTER_BONSAI $REPOIDLARGE $LARGE_MASTER_BONSAI
|
||||
$ add_synced_commit_mapping_entry $REPOIDSMALL2 $SMALL2_MASTER_BONSAI $REPOIDLARGE $LARGE_MASTER_BONSAI
|
||||
$ sqlite3 "$TESTTMP/monsql/sqlite_dbs" "INSERT INTO mutable_counters (repo_id, name, value) VALUES ($REPOIDSMALL1, 'backsync_from_$REPOIDLARGE', 2)";
|
||||
|
||||
Normal pushrebase with one commit
|
||||
$ cd "$TESTTMP/small-hg-client-1"
|
||||
$ REPONAME=small-mon-1 hgmn up -q master_bookmark
|
||||
$ echo 2 > 2 && hg addremove -q && hg ci -q -m newcommit
|
||||
$ REPONAME=small-mon-1 hgmn push -r . --to master_bookmark | grep updating
|
||||
updating bookmark master_bookmark
|
||||
-- newcommit was correctly pushed to master_bookmark
|
||||
$ log -r master_bookmark
|
||||
@ newcommit [public;rev=2;6989db12d1e5] default/master_bookmark
|
||||
|
|
||||
~
|
||||
|
||||
-- newcommit is also present in the large repo (after a pull)
|
||||
$ cd "$TESTTMP"/large-hg-client
|
||||
$ log -r master_bookmark
|
||||
o first post-move commit [public;rev=3;bca7e9574548] default/master_bookmark
|
||||
|
|
||||
~
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
$ log -r master_bookmark
|
||||
o newcommit [public;rev=4;7c9a729ceb57] default/master_bookmark
|
||||
|
|
||||
~
|
||||
- compare the working copies
|
||||
$ verify_wc master_bookmark
|
||||
|
||||
At the same time, the tailed repo gets new commits
|
||||
$ cd "$TESTTMP/small-hg-client-2"
|
||||
$ REPONAME=small-mon-2 hgmn up -q master_bookmark
|
||||
$ createfile file2_1
|
||||
$ hg ci -qm "Post-merge commit 1"
|
||||
$ REPONAME=small-mon-2 hgmn push --to master_bookmark -q
|
||||
-- tailer puts this commit into a large repo
|
||||
$ mononoke_x_repo_sync_once $REPOIDSMALL2 $REPOIDLARGE master_bookmark once --commit master_bookmark 2>&1 | grep "synced as"
|
||||
* public changeset 46d7f49c05a72a305692183a11274a0fbbdc4f8a4b53ca759fb3d257ba54184e synced as 3a9ffb4771519f86b79729a543da084c6a70ff385933aed540e2112a049a0697 * (glob)
|
||||
|
||||
Force pushrebase should fail, because it pushes to a shared bookmark
|
||||
$ cd "$TESTTMP/small-hg-client-1"
|
||||
$ REPONAME=small-mon-1 hgmn up -q master_bookmark^
|
||||
$ echo 3 > 3 && hg add 3 && hg ci -q -m "non-forward move"
|
||||
$ REPONAME=small-mon-1 hgmn push --to master_bookmark --force --pushvar NON_FAST_FORWARD=true | grep updating
|
||||
remote: Command failed
|
||||
remote: Error:
|
||||
remote: cannot force pushrebase to shared bookmark master_bookmark
|
||||
remote: Root cause:
|
||||
remote: ErrorMessage {
|
||||
remote: msg: "cannot force pushrebase to shared bookmark master_bookmark",
|
||||
remote: }
|
||||
abort: stream ended unexpectedly (got 0 bytes, expected 4)
|
||||
[1]
|
||||
|
||||
Non-shared bookmark should work
|
||||
$ REPONAME=small-mon-1 hgmn push --to master_bookmark_non_fast_forward --force --create -q
|
||||
-- it should also be present in a large repo
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
$ log -r bookprefix1/master_bookmark_non_fast_forward
|
||||
o non-forward move [public;rev=5;6b6a308437bb] default/bookprefix1/master_bookmark_non_fast_forward
|
||||
|
|
||||
~
|
||||
|
||||
Bookmark-only pushrebase (Create a new bookmark, do not push commits)
|
||||
$ cd "$TESTTMP/small-hg-client-1"
|
||||
$ REPONAME=small-mon-1 hgmn push -r master_bookmark^ --to master_bookmark_2 --create | grep exporting
|
||||
exporting bookmark master_bookmark_2
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/master_bookmark 2:6989db12d1e5
|
||||
default/master_bookmark_2 1:680aaf36d7a2
|
||||
default/master_bookmark_non_fast_forward 3:161addaa86c7
|
||||
-- this is not a `common_pushrebase_bookmark`, so should be prefixed
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
devel-warn: applied empty changegroup at: * (glob)
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/bookprefix1/master_bookmark_2 3:bca7e9574548
|
||||
default/bookprefix1/master_bookmark_non_fast_forward 5:6b6a308437bb
|
||||
default/master_bookmark 6:bf8e8d65212d
|
||||
- compare the working copies
|
||||
$ verify_wc bookprefix1/master_bookmark_2
|
||||
|
||||
Delete a bookmark
|
||||
$ cd "$TESTTMP/small-hg-client-1"
|
||||
$ REPONAME=small-mon-1 hgmn push -d master_bookmark_2 | grep deleting
|
||||
deleting remote bookmark master_bookmark_2
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/master_bookmark 2:6989db12d1e5
|
||||
default/master_bookmark_non_fast_forward 3:161addaa86c7
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
devel-warn: applied empty changegroup at: * (glob)
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/bookprefix1/master_bookmark_non_fast_forward 5:6b6a308437bb
|
||||
default/master_bookmark 6:bf8e8d65212d
|
@ -116,33 +116,13 @@ Normal pushrebase with one commit
|
||||
- compare the working copies
|
||||
$ verify_wc master_bookmark
|
||||
|
||||
Force pushrebase
|
||||
$ cd "$TESTTMP/small-hg-client"
|
||||
$ REPONAME=small-mon hgmn up -q master_bookmark^
|
||||
$ echo 3 > 3 && hg add 3 && hg ci -q -m "Master after non-forward move"
|
||||
$ REPONAME=small-mon hgmn push --to master_bookmark --force --pushvar NON_FAST_FORWARD=true | grep updating
|
||||
updating bookmark master_bookmark
|
||||
$ log -r master_bookmark
|
||||
@ Master after non-forward move [public;rev=3;e5ca36a3d680] default/master_bookmark
|
||||
|
|
||||
~
|
||||
-- it should also be present in a large repo
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
$ log -r master_bookmark
|
||||
o Master after non-forward move [public;rev=4;373fa4f55174] default/master_bookmark
|
||||
|
|
||||
~
|
||||
- compare the working copies
|
||||
$ verify_wc master_bookmark
|
||||
|
||||
Bookmark-only pushrebase (Create a new bookmark, do not push commits)
|
||||
$ cd "$TESTTMP/small-hg-client"
|
||||
$ REPONAME=small-mon hgmn push -r master_bookmark^ --to master_bookmark_2 --create | grep exporting
|
||||
exporting bookmark master_bookmark_2
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/master_bookmark 3:e5ca36a3d680
|
||||
default/master_bookmark 2:ce81c7d38286
|
||||
default/master_bookmark_2 1:11f848659bfc
|
||||
-- this is not a `common_pushrebase_bookmark`, so should be prefixed
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
@ -151,7 +131,7 @@ Bookmark-only pushrebase (Create a new bookmark, do not push commits)
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/bookprefix/master_bookmark_2 2:bfcfb674663c
|
||||
default/master_bookmark 4:373fa4f55174
|
||||
default/master_bookmark 3:819e91b238b7
|
||||
- compare the working copies
|
||||
$ verify_wc bookprefix/master_bookmark_2
|
||||
|
||||
@ -161,13 +141,13 @@ Delete a bookmark
|
||||
deleting remote bookmark master_bookmark_2
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/master_bookmark 3:e5ca36a3d680
|
||||
default/master_bookmark 2:ce81c7d38286
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
devel-warn: applied empty changegroup at: * (glob)
|
||||
$ hg book --all
|
||||
no bookmarks set
|
||||
default/master_bookmark 4:373fa4f55174
|
||||
default/master_bookmark 3:819e91b238b7
|
||||
|
||||
Normal pushrebase with many commits
|
||||
$ cd "$TESTTMP/small-hg-client"
|
||||
@ -178,7 +158,7 @@ Normal pushrebase with many commits
|
||||
$ createfile 7 && hg ci -qm "The staunchest tramp to ply his trade"
|
||||
|
||||
$ REPONAME=small-mon hgmn push --to master_bookmark
|
||||
pushing rev 5448ef1ede9d to destination ssh://user@dummy/small-mon bookmark master_bookmark
|
||||
pushing rev beb30dc3a35c to destination ssh://user@dummy/small-mon bookmark master_bookmark
|
||||
searching for changes
|
||||
adding changesets
|
||||
adding manifests
|
||||
@ -186,14 +166,14 @@ Normal pushrebase with many commits
|
||||
added 0 changesets with 0 changes to 0 files
|
||||
updating bookmark master_bookmark
|
||||
$ log -r master_bookmark
|
||||
@ The staunchest tramp to ply his trade [public;rev=7;5448ef1ede9d] default/master_bookmark
|
||||
@ The staunchest tramp to ply his trade [public;rev=6;beb30dc3a35c] default/master_bookmark
|
||||
|
|
||||
~
|
||||
-- this should also be present in a large repo, once we pull:
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
$ log -r master_bookmark
|
||||
o The staunchest tramp to ply his trade [public;rev=8;73bd0869f142] default/master_bookmark
|
||||
o The staunchest tramp to ply his trade [public;rev=7;34c34be6efde] default/master_bookmark
|
||||
|
|
||||
~
|
||||
$ verify_wc master_bookmark
|
||||
@ -208,14 +188,14 @@ Pushrebase, which deletes and removes files
|
||||
$ REPONAME=small-mon hgmn push --to master_bookmark | grep updating
|
||||
updating bookmark master_bookmark
|
||||
$ log -r master_bookmark
|
||||
@ Moves, renames and copies [public;rev=8;ed440ae481ea] default/master_bookmark
|
||||
@ Moves, renames and copies [public;rev=7;b888ee4f19b5] default/master_bookmark
|
||||
|
|
||||
~
|
||||
-- this should also be present in a large repo, once we pull:
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
$ log -r master_bookmark
|
||||
o Moves, renames and copies [public;rev=9;ba47ebe8e77d] default/master_bookmark
|
||||
o Moves, renames and copies [public;rev=8;b4e3e504160c] default/master_bookmark
|
||||
|
|
||||
~
|
||||
$ verify_wc master_bookmark
|
||||
@ -229,14 +209,14 @@ Pushrebase, which replaces a directory with a file
|
||||
$ REPONAME=small-mon hgmn push --to master_bookmark | grep updating
|
||||
updating bookmark master_bookmark
|
||||
$ log -r master_bookmark
|
||||
@ Replace a directory with a file [public;rev=9;e8e60f4bf53e] default/master_bookmark
|
||||
@ Replace a directory with a file [public;rev=8;e72ee383159a] default/master_bookmark
|
||||
|
|
||||
~
|
||||
-- this should also be present in a large repo, once we pull
|
||||
$ cd "$TESTTMP/large-hg-client"
|
||||
$ REPONAME=large-mon hgmn pull -q
|
||||
$ log -r master_bookmark
|
||||
o Replace a directory with a file [public;rev=10;63366cd3030b] default/master_bookmark
|
||||
o Replace a directory with a file [public;rev=9;6ac00e7afd93] default/master_bookmark
|
||||
|
|
||||
~
|
||||
$ verify_wc master_bookmark
|
||||
|
Loading…
Reference in New Issue
Block a user