diff --git a/creation_repo.sh b/creation_repo.sh index d7cdec3..346a792 100755 --- a/creation_repo.sh +++ b/creation_repo.sh @@ -19,10 +19,10 @@ create_random_file(){ dd if=/dev/urandom of=$1 bs=$2 count=1 &> /dev/null } -REPO_NAME=performance_testing +REPO_NAME=git_update_testing REPO_PATH=./remote WITH_SUBMODULE="false" -SUB_NAME="submodule_for_performance_testing" +SUB_NAME="submodule" WITH_LINK="false" while getopts ":hn:sl:" option; do case $option in @@ -84,7 +84,7 @@ if [ ! -d $REPO_NAME ]; then git add . git commit -m"first 1M sample created" cd ../$REPO_NAME - git submodule add ../submodule_for_performance_testing + git submodule add ../$SUB_NAME git commit -am "adding $SUB_NAME module" fi cd .. @@ -99,7 +99,7 @@ else # $REPO_NAME exists git add . git commit -m"first 1M sample created" cd ../$REPO_NAME - git submodule add ../submodule_for_performance_testing + git submodule add ../$SUB_NAME git commit -am "adding $SUB_NAME module" elif [[ "$WITH_SUBMODULE" != "true" && -d $SUB_NAME ]]; then cd $REPO_NAME diff --git a/git_update.sh b/git_update.sh index c60834c..2056059 100755 --- a/git_update.sh +++ b/git_update.sh @@ -1,46 +1,43 @@ #!/bin/bash -summary="$0 [options] " -ref=main -dst='.' -nonempty_target=false -use_home=false -be_aggressive=false - Help(){ echo " NAME git_update.sh SYNOPSIS - git_update.sh [-h] [-r ref] [-d dest] [-H] [-N] [-a] repository + git_update.sh [-h] [-r ref] [-d dest] [-H] [-a] repository OPTIONS - -h prints the help. + -h prints the help. -r specifies the reference to the commit to be synchronized. It can be a tag or a branch. By default, it is the last commit of branch main. - -d specifies the destination of the clone or update. If non-empty, -N must be specified. - -H - -N indicates that the destination is non-empty. The files that do not conflict and if it is an update, are not committed, will be kept. - -a specifies that the aggressive option of git clean must be used. git clean is called wen -N is not specified. + -d specifies the destination of the clone or update. Directory must be empty if a new clone is to be made. If the repository to be cloned is local, and its path is passed as a relative path, the path should start from the destination. - To avoid mistakes, absolute paths are advised. - + To avoid mistakes, absolute paths are advised. + -H allows the $HOME directory to be used by git_update.sh. By default, git_update.sh cannot access $HOME to prevent default behavior. + If you need the global .gitconfig located in your $HOME to be used, you should supply the -H option. + -a specifies that the aggressive option of the git garbage collection must be used. Only advised when changes happen in many different objects. Will slow down the execution. DESCRIPTION - This script will replace the destination with the wanted commit of a git repository. The history is not preserved but tags are. + This script will replace the destination with the wanted commit of a git repository. The history is not preserved but tags are. Untracked files remain. The git commands have been chosen so as to minimize the memory and bandwidth usages." } -while getopts ":hr:d:NHa" option; do +#variables +summary="$0 [options] " +ref=main +dst='.' +use_home=false +be_aggressive="false" + +while getopts ":hr:d:H" option; do case $option in h) # display Help Help exit;; - r) # branch or tag wanted + r) # desired branch or tag ref="$OPTARG";; d) # destination of clone dst="$OPTARG";; - N) # clone to a Non-empty target. Existing files will be overwritten - nonempty_target="true";; H) # use real home dir - use_home="false";; - a) # use git clean with the aggressive option + use_home="true";; + a) #use -a in git gc call be_aggressive="true";; \?) # invalid option echo "Error: Invalid option here" @@ -49,7 +46,6 @@ while getopts ":hr:d:NHa" option; do done shift $((OPTIND-1)) - repo="$1" if [ -z "$repo" ] ; then exit "$0: Empty repo given\n$summary" @@ -64,36 +60,21 @@ fi mkdir -p "$dst" cd "$dst" - if [ -d .git ] ; then - - git submodule update --init --recursive --force --depth=1 --remote + echo "updating..." git fetch --tags --depth=1 --prune --prune-tags --force origin $ref - git reset --hard FETCH_HEAD + git reset --hard --recurse-submodules FETCH_HEAD + git submodule update --init --recursive --force --depth=1 --remote + #garbage collection of anything unreachable at the moment git reflog expire --expire=now --all if "$be_aggressive" ; then git gc --prune=now --aggressive - else + elsels git gc --prune=now fi - # Preserve existing files in some cases - if ! "$nonempty_target" ; then #we keep uncommitted files when in -N mode - git clean -qfdx - fi - else +echo "cloning..." clone_dst='.' - - # To override an existing dir, we need to clone elsewhere first - if "$nonempty_target" ; then - clone_dst="$(mktemp -d)" - fi git clone -b "$ref" --recurse-submodules --shallow-submodules --depth 1 "$repo" "$clone_dst" - - # To override an existing dir, we then move everything to that dir - if "$nonempty_target" ; then - mv "$clone_dst/"{*,.*} . - rmdir "$clone_dst" - fi fi diff --git a/test_git_update.sh b/test_git_update.sh index eab0f60..eccedbc 100755 --- a/test_git_update.sh +++ b/test_git_update.sh @@ -24,15 +24,17 @@ DESCRIPTION TEST6: git updated, switching to another branch, deleting and adding files in the process TEST7: git updated, switching to a tag, deleting and adding files in the process TEST8: git updated, before and after changing a tag, deleting and adding files in the process + TEST9: git updated fast-forward on submodule on main " } #Variables definitions WORKING_DIRECTORY=$(pwd) -REMOTE="file://${WORKING_DIRECTORY}/remote/git_update_testing" #we must trick git_update.sh into thinking we are not working in local, otherwise depth=1 is not respected -LOCAL_REMOTE="/${WORKING_DIRECTORY}/remote/git_update_testing" #cd does not understand file:// REPO_NAME="git_update_testing" -WITH_SUBMODULE="true" +SUBMODULE_NAME="submodule" +REMOTE="file://${WORKING_DIRECTORY}/remote/$REPO_NAME" #we must trick git_update.sh into thinking we are not working in local, otherwise depth=1 is not respected +LOCAL_REMOTE="/${WORKING_DIRECTORY}/remote/$REPO_NAME" #cd does not understand file:// +LOCAL_REMOTE_SUBMODULE="/${WORKING_DIRECTORY}/remote/$SUBMODULE_NAME" FILENAMES=("sample0" "sample1 sample3") FILENAMES_TAG=("sample0 sample1 sample4") FILENAMES_BRANCH=("sample0 sample1 sample2") @@ -40,6 +42,7 @@ FILE_ON_BRANCH_ONLY="sample2" FILE_ON_TAG_ONLY="sample4" FILE_ON_MAIN_ONLY="sample3" FILE_TO_BE_DELETED="sample0" +FILE_TO_BE_DELETED_SUBMODULE="sub_sample0" FILE_TO_BE_CREATED="new_file" FILE_TO_BE_MODIFIED=$FILE_TO_BE_CREATED UNTRACKED_FILE="untracked_file" @@ -47,12 +50,13 @@ TAG_NAME="tagging_point" TAG_FLAG="tag_flag" BRANCH_NAME="secondary" -bash creation_repo.sh -s &> /dev/null +bash creation_repo.sh -s #&> /dev/null #output function section(){ echo "------------------------------ $1 ------------------------------" } + #check functions cloning_check(){ local input=("$@") @@ -156,6 +160,26 @@ modification_check(){ cd .. } +modification_submodule_check(){ + local repo_name=$1 + cd $repo_name/$SUBMODULE_NAME + if [ -f $FILE_TO_BE_CREATED ]; then + echo "The new file has been imported." + modification_submodule_result=0 + + else + echo "The new file has not been imported." + modification_submodule_result="1" + fi + if [ -f "$FILE_TO_BE_DELETED_SUBMODULE" ]; then + echo "$FILE_TO_BE_DELETED_SUBMODULE has not been deleted." + modification_submodule_result="1" + else + echo "$FILE_TO_BE_DELETED_SUBMODULE has been deleted." + fi + cd .. +} + switching_branch_check(){ local repo_name=$1 cd $repo_name @@ -210,23 +234,39 @@ conflict_check(){ #intermediate functions modification_remote(){ - echo "remote : $LOCAL_REMOTE" - echo "pwd : $(pwd)" cd $LOCAL_REMOTE touch $FILE_TO_BE_CREATED echo "new text" > $FILE_TO_BE_CREATED rm $FILE_TO_BE_DELETED git add $FILE_TO_BE_CREATED $FILE_TO_BE_DELETED &> /dev/null - git commit -m "$FILE_TO_BE_CREATED created and $FILE_TO_BE_DELETED deleted" #&> /dev/null + git commit -m "$FILE_TO_BE_CREATED created and $FILE_TO_BE_DELETED deleted" &> /dev/null cd ../.. } + undo_modification_remote(){ cd $LOCAL_REMOTE git revert --no-edit HEAD &> /dev/null cd ../.. } +modification_submodule(){ + cd $LOCAL_REMOTE_SUBMODULE + pwd + touch $FILE_TO_BE_CREATED + echo "new text" > $FILE_TO_BE_CREATED + rm $FILE_TO_BE_DELETED_SUBMODULE + git add $FILE_TO_BE_CREATED $FILE_TO_BE_DELETED_SUBMODULE &> /dev/null + git commit -m "$FILE_TO_BE_CREATED created and $FILE_TO_BE_DELETED_SUBMODULE deleted" #&> /dev/null + cd ../.. +} + +undo_modification_submodule(){ + cd $LOCAL_REMOTE_SUBMODULE + git revert --no-edit HEAD &> /dev/null + cd ../.. +} + add_untracked_file(){ local repo_name=$1 cd $repo_name @@ -265,7 +305,8 @@ undo_changing_tag(){ git checkout $TAG_FLAG &> /dev/null git tag -f $TAG_NAME &> /dev/null #move locally git tag --delete $TAG_FLAG &> /dev/null #delete locally - cd .. + git checkout main &> /dev/null + cd ../.. } @@ -276,7 +317,7 @@ test0 (){ if [ -d $REPO_NAME ]; then rm -rf $REPO_NAME fi - ./git_update.sh -d $REPO_NAME $REMOTE #&> /dev/null + ./git_update.sh -d $REPO_NAME $REMOTE &> /dev/null #checks cloning_check $REPO_NAME ${FILENAMES[@]} history_check $REPO_NAME @@ -318,7 +359,7 @@ test2(){ fi ./git_update.sh -d $REPO_NAME -r $BRANCH_NAME $REMOTE &> /dev/null #checks - cloning_check $REPO_NAME ${FILENAMES_BRANCH[@]} #we do not check for all files, especially not those specific to the branch. + cloning_check $REPO_NAME ${FILENAMES_BRANCH[@]} history_check $REPO_NAME branch_check $REPO_NAME @@ -339,7 +380,7 @@ test3(){ fi #clone the repo in its last state git clone --recurse-submodules --shallow-submodules --depth 1 $REMOTE &> /dev/null - #modify the remote from elsewhere + #modify the remote modification_remote #make git_update.sh update the repository cd $REPO_NAME @@ -368,7 +409,7 @@ test4(){ fi #clone the repo in its last state git clone --recurse-submodules --shallow-submodules --depth 1 $REMOTE &> /dev/null - #modify the remote from elsewhere + #modify the remote modification_remote #add an untracked file add_untracked_file $REPO_NAME @@ -384,11 +425,11 @@ test4(){ undo_modification_remote remove_untracked_file $REPO_NAME - case3=$((modification_result+history_result+untracked_result)) - if [ "$case3" = "0" ]; then - echo "case 3, fast-forward update on main: OK" + case4=$((modification_result+history_result+untracked_result)) + if [ "$case4" = "0" ]; then + echo "case 4, fast-forward update on main with untracked file: OK" else - echo "case 3, fast-forward update on main: FAIL" + echo "case 4, fast-forward update on main with untracked file: FAIL" fi } @@ -403,7 +444,7 @@ test5(){ git clone --recurse-submodules --shallow-submodules --depth 1 $REMOTE &> /dev/null #modify the local repo modification_local $REPO_NAME - #modify the remote from elsewhere + #modify the remote modification_remote #make git_update.sh update the local repository cd $REPO_NAME @@ -481,21 +522,18 @@ test8(){ git clone --recurse-submodules --shallow-submodules --depth 1 $REMOTE &> /dev/null #call git_update.sh with a tag cd $REPO_NAME - ../git_update.sh -r $TAG_NAME $REMOTE #&> /dev/null + ../git_update.sh -r $TAG_NAME $REMOTE &> /dev/null cd .. #intermediate check to make sure that we are starting on the initial position of the tag - echo "first position of the tag" - pwd switching_tag_check $REPO_NAME - #change the position of the tag from elsewhere + #change the position of the tag changing_tag #call git_update.sh again to go to the new position of the tag cd $REPO_NAME - pwd - ../git_update.sh -r $TAG_NAME $REMOTE #&> /dev/null + ../git_update.sh -r $TAG_NAME $REMOTE &> /dev/null cd .. #put back the remote in its initial state - #undo_changing_tag + undo_changing_tag #checks echo "second position of the tag" @@ -507,9 +545,38 @@ test8(){ else echo "case 8, tag-changing update: FAIL" fi - } +test9(){ +#CASE 9: git updated fast-forward on submodule on main + section TEST9 + #if it exists, delete the directory + if [ -d $REPO_NAME ]; then + rm -rf $REPO_NAME + fi + #clone the repo in its last state + git clone --recurse-submodules --shallow-submodules --depth 1 $REMOTE &> /dev/null + #modify the remote + modification_submodule + #make git_update.sh update the repository + cd $REPO_NAME + echo "moment fatidique" + ../git_update.sh $REMOTE #&> /dev/null + cd .. + #checks + modification_submodule_check $REPO_NAME + history_check $REPO_NAME + #cleaning + undo_modification_submodule + + case9=$((modification_submodule_result+history_result)) + if [ "$case9" = "0" ]; then + echo "case 9, fast-forward update on submodule on main: OK" + else + echo "case 9, fast-forward update on submodule on main: FAIL" + fi +} + while getopts ":hn:a" option; do case $option in h) # display Help @@ -535,6 +602,7 @@ if [ "$ALL_TESTS" = "true" ]; then test6 test7 test8 + test9 elif [ -n "$TEST_NUM" ]; then #in order to only create the temporary clone once if we execute all tests case $TEST_NUM in @@ -556,6 +624,8 @@ elif [ -n "$TEST_NUM" ]; then test7;; 8) test8;; + 9) + test9;; *) echo "Error: Invalid test number" exit;;