github.com/git-lfs/git-lfs@v2.5.2+incompatible/t/t-migrate-export.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  . "$(dirname "$0")/fixtures/migrate.sh"
     4  . "$(dirname "$0")/testlib.sh"
     5  
     6  begin_test "migrate export (default branch)"
     7  (
     8    set -e
     9  
    10    setup_multiple_local_branches_tracked
    11  
    12    # Add b.md, a pointer existing only on master
    13    base64 < /dev/urandom | head -c 160 > b.md
    14    git add b.md
    15    git commit -m "add b.md"
    16  
    17    md_oid="$(calc_oid "$(cat a.md)")"
    18    txt_oid="$(calc_oid "$(cat a.txt)")"
    19    b_md_oid="$(calc_oid "$(cat b.md)")"
    20  
    21    git checkout my-feature
    22    md_feature_oid="$(calc_oid "$(cat a.md)")"
    23    git checkout master
    24  
    25    assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
    26    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "120"
    27    assert_pointer "refs/heads/master" "b.md" "$b_md_oid" "160"
    28    assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
    29  
    30    git lfs migrate export --include="*.md, *.txt"
    31  
    32    refute_pointer "refs/heads/master" "a.md"
    33    refute_pointer "refs/heads/master" "a.txt"
    34    refute_pointer "refs/heads/master" "b.md"
    35    assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
    36  
    37    # b.md should be pruned as no pointer exists to reference it
    38    refute_local_object "$b_md_oid" "160"
    39  
    40    # Other objects should not be pruned as they're still referenced in `feature`
    41    # by pointers
    42    assert_local_object "$md_oid" "140"
    43    assert_local_object "$txt_oid" "120"
    44    assert_local_object "$md_feature_oid" "30"
    45  
    46    master="$(git rev-parse refs/heads/master)"
    47    feature="$(git rev-parse refs/heads/my-feature)"
    48  
    49    master_attrs="$(git cat-file -p "$master:.gitattributes")"
    50    feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
    51  
    52    echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
    53    echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
    54  
    55    [ ! $(echo "$feature_attrs" | grep -q "*.md text !filter !merge !diff") ]
    56    [ ! $(echo "$feature_attrs" | grep -q "*.txt text !filter !merge !diff") ]
    57  )
    58  end_test
    59  
    60  begin_test "migrate export (with remote)"
    61  (
    62    set -e
    63  
    64    setup_single_remote_branch_tracked
    65  
    66    git push origin master
    67  
    68    md_oid="$(calc_oid "$(cat a.md)")"
    69    txt_oid="$(calc_oid "$(cat a.txt)")"
    70  
    71    assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
    72    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
    73  
    74    assert_pointer "refs/remotes/origin/master" "a.md" "$md_oid" "50"
    75    assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_oid" "30"
    76  
    77    # Flush the cache to ensure all objects have to be downloaded
    78    rm -rf .git/lfs/objects
    79  
    80    git lfs migrate export --everything --include="*.md, *.txt"
    81  
    82    refute_pointer "refs/heads/master" "a.md"
    83    refute_pointer "refs/heads/master" "a.txt"
    84  
    85    # All pointers have been exported, so all objects should be pruned
    86    refute_local_object "$md_oid" "50"
    87    refute_local_object "$txt_oid" "30"
    88  
    89    master="$(git rev-parse refs/heads/master)"
    90    master_attrs="$(git cat-file -p "$master:.gitattributes")"
    91  
    92    echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
    93    echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
    94  )
    95  end_test
    96  
    97  begin_test "migrate export (include/exclude args)"
    98  (
    99    set -e
   100  
   101    setup_single_local_branch_tracked
   102  
   103    md_oid="$(calc_oid "$(cat a.md)")"
   104    txt_oid="$(calc_oid "$(cat a.txt)")"
   105  
   106    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "120"
   107    assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
   108  
   109    git lfs migrate export --include="*" --exclude="a.md"
   110  
   111    refute_pointer "refs/heads/master" "a.txt"
   112    assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
   113  
   114    refute_local_object "$txt_oid" "120"
   115    assert_local_object "$md_oid" "140"
   116  
   117    master="$(git rev-parse refs/heads/master)"
   118  
   119    master_attrs="$(git cat-file -p "$master:.gitattributes")"
   120  
   121    echo "$master_attrs" | grep -q "* text !filter !merge !diff"
   122    echo "$master_attrs" | grep -q "a.md filter=lfs diff=lfs merge=lfs"
   123  )
   124  end_test
   125  
   126  begin_test "migrate export (bare repository)"
   127  (
   128    set -e
   129  
   130    setup_single_remote_branch_tracked
   131    git push origin master
   132  
   133    md_oid="$(calc_oid "$(cat a.md)")"
   134    txt_oid="$(calc_oid "$(cat a.txt)")"
   135  
   136    make_bare
   137  
   138    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
   139    assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
   140  
   141    git lfs migrate export --everything --include="*"
   142  
   143    refute_pointer "refs/heads/master" "a.md"
   144    refute_pointer "refs/heads/master" "a.txt"
   145  
   146    # All pointers have been exported, so all objects should be pruned
   147    refute_local_object "$md_oid" "50"
   148    refute_local_object "$txt_oid" "30"
   149  )
   150  end_test
   151  
   152  begin_test "migrate export (given branch)"
   153  (
   154    set -e
   155  
   156    setup_multiple_local_branches_tracked
   157  
   158    md_oid="$(calc_oid "$(cat a.md)")"
   159    txt_oid="$(calc_oid "$(cat a.txt)")"
   160  
   161    git checkout my-feature
   162    md_feature_oid="$(calc_oid "$(cat a.md)")"
   163    git checkout master
   164  
   165    assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "30"
   166    assert_pointer "refs/heads/my-feature" "a.txt" "$txt_oid" "120"
   167    assert_pointer "refs/heads/master" "a.md" "$md_oid" "140"
   168    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "120"
   169  
   170    git lfs migrate export --include="*.md,*.txt" my-feature
   171  
   172    refute_pointer "refs/heads/my-feature" "a.md"
   173    refute_pointer "refs/heads/my-feature" "a.txt"
   174    refute_pointer "refs/heads/master" "a.md"
   175    refute_pointer "refs/heads/master" "a.txt"
   176  
   177    # No pointers left, so all objects should be pruned
   178    refute_local_object "$md_feature_oid" "30"
   179    refute_local_object "$txt_oid" "120"
   180    refute_local_object "$md_oid" "140"
   181  
   182    master="$(git rev-parse refs/heads/master)"
   183    feature="$(git rev-parse refs/heads/my-feature)"
   184  
   185    master_attrs="$(git cat-file -p "$master:.gitattributes")"
   186    feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
   187  
   188    echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
   189    echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
   190    echo "$feature_attrs" | grep -q "*.md text !filter !merge !diff"
   191    echo "$feature_attrs" | grep -q "*.txt text !filter !merge !diff"
   192  )
   193  end_test
   194  
   195  begin_test "migrate export (no filter)"
   196  (
   197    set -e
   198  
   199    setup_multiple_local_branches_tracked
   200  
   201    git lfs migrate export --yes 2>&1 | tee migrate.log
   202    if [ ${PIPESTATUS[0]} -eq 0 ]; then
   203      echo >&2 "fatal: expected git lfs migrate export to fail, didn't"
   204      exit 1
   205    fi
   206  
   207    grep "fatal: one or more files must be specified with --include" migrate.log
   208  )
   209  end_test
   210  
   211  begin_test "migrate export (exclude remote refs)"
   212  (
   213    set -e
   214  
   215    setup_single_remote_branch_tracked
   216  
   217    md_oid="$(calc_oid "$(cat a.md)")"
   218    txt_oid="$(calc_oid "$(cat a.txt)")"
   219  
   220    git checkout refs/remotes/origin/master
   221    md_remote_oid="$(calc_oid "$(cat a.md)")"
   222    txt_remote_oid="$(calc_oid "$(cat a.txt)")"
   223    git checkout master
   224  
   225    assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
   226    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
   227  
   228    assert_pointer "refs/remotes/origin/master" "a.md" "$md_remote_oid" "140"
   229    assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_remote_oid" "120"
   230  
   231    git lfs migrate export --include="*.md,*.txt"
   232  
   233    refute_pointer "refs/heads/master" "a.md"
   234    refute_pointer "refs/heads/master" "a.txt"
   235  
   236    refute_local_object "$md_oid" "50"
   237    refute_local_object "$txt_oid" "30"
   238  
   239    assert_pointer "refs/remotes/origin/master" "a.md" "$md_remote_oid" "140"
   240    assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_remote_oid" "120"
   241  
   242    # Since these two objects exist on the remote, they should be removed with
   243    # our prune operation
   244    refute_local_object "$md_remote_oid" "140"
   245    refute_local_object "$txt_remote_oid" "120"
   246  
   247    master="$(git rev-parse refs/heads/master)"
   248    remote="$(git rev-parse refs/remotes/origin/master)"
   249  
   250    master_attrs="$(git cat-file -p "$master:.gitattributes")"
   251    remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
   252  
   253    echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
   254    echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
   255  
   256    [ ! $(echo "$remote_attrs" | grep -q "*.md text !filter !merge !diff") ]
   257    [ ! $(echo "$remote_attrs" | grep -q "*.txt text !filter !merge !diff") ]
   258  )
   259  end_test
   260  
   261  begin_test "migrate export (--skip-fetch)"
   262  (
   263    set -e
   264  
   265    setup_single_remote_branch_tracked
   266  
   267    md_master_oid="$(calc_oid "$(cat a.md)")"
   268    txt_master_oid="$(calc_oid "$(cat a.txt)")"
   269  
   270    git checkout refs/remotes/origin/master
   271    md_remote_oid="$(calc_oid "$(cat a.md)")"
   272    txt_remote_oid="$(calc_oid "$(cat a.txt)")"
   273    git checkout master
   274  
   275    git tag pseudo-remote "$(git rev-parse refs/remotes/origin/master)"
   276    # Remove the refs/remotes/origin/master ref, and instruct 'git lfs migrate' to
   277    # not fetch it.
   278    git update-ref -d refs/remotes/origin/master
   279  
   280    assert_pointer "refs/heads/master" "a.md" "$md_master_oid" "50"
   281    assert_pointer "pseudo-remote" "a.md" "$md_remote_oid" "140"
   282    assert_pointer "refs/heads/master" "a.txt" "$txt_master_oid" "30"
   283    assert_pointer "pseudo-remote" "a.txt" "$txt_remote_oid" "120"
   284  
   285    git lfs migrate export --skip-fetch --include="*.md,*.txt"
   286  
   287    refute_pointer "refs/heads/master" "a.md"
   288    refute_pointer "pseudo-remote" "a.md"
   289    refute_pointer "refs/heads/master" "a.txt"
   290    refute_pointer "pseudo-remote" "a.txt"
   291  
   292    refute_local_object "$md_master_oid" "50"
   293    refute_local_object "$md_remote_oid" "140"
   294    refute_local_object "$txt_master_oid" "30"
   295    refute_local_object "$txt_remote_oid" "120"
   296  
   297    master="$(git rev-parse refs/heads/master)"
   298    remote="$(git rev-parse pseudo-remote)"
   299  
   300    master_attrs="$(git cat-file -p "$master:.gitattributes")"
   301    remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
   302  
   303    echo "$master_attrs" | grep -q "*.md text !filter !merge !diff"
   304    echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff"
   305    echo "$remote_attrs" | grep -q "*.md text !filter !merge !diff"
   306    echo "$remote_attrs" | grep -q "*.txt text !filter !merge !diff"
   307  )
   308  end_test
   309  
   310  begin_test "migrate export (include/exclude ref)"
   311  (
   312    set -e
   313  
   314    setup_multiple_remote_branches_gitattrs
   315  
   316    md_master_oid="$(calc_oid "$(cat a.md)")"
   317    txt_master_oid="$(calc_oid "$(cat a.txt)")"
   318  
   319    git checkout refs/remotes/origin/master
   320    md_remote_oid="$(calc_oid "$(cat a.md)")"
   321    txt_remote_oid="$(calc_oid "$(cat a.txt)")"
   322  
   323    git checkout my-feature
   324    md_feature_oid="$(calc_oid "$(cat a.md)")"
   325    txt_feature_oid="$(calc_oid "$(cat a.txt)")"
   326  
   327    git checkout master
   328  
   329    git lfs migrate export \
   330      --include="*.txt" \
   331      --include-ref=refs/heads/my-feature \
   332      --exclude-ref=refs/heads/master
   333  
   334    assert_pointer "refs/heads/master" "a.md" "$md_master_oid" "21"
   335    assert_pointer "refs/heads/master" "a.txt" "$txt_master_oid" "20"
   336  
   337    assert_pointer "refs/remotes/origin/master" "a.md" "$md_remote_oid" "11"
   338    assert_pointer "refs/remotes/origin/master" "a.txt" "$txt_remote_oid" "10"
   339  
   340    assert_pointer "refs/heads/my-feature" "a.md" "$md_feature_oid" "31"
   341    refute_pointer "refs/heads/my-feature" "a.txt"
   342  
   343    # Master objects should not be pruned as they exist in unpushed commits
   344    assert_local_object "$md_master_oid" "21"
   345    assert_local_object "$txt_master_oid" "20"
   346  
   347    # Remote master objects should be pruned as they exist in the remote
   348    refute_local_object "$md_remote_oid" "11"
   349    refute_local_object "$txt_remote_oid" "10"
   350  
   351    # txt_feature_oid should be pruned as it's no longer a pointer, but
   352    # md_feature_oid should remain as it's still a pointer in unpushed commits
   353    assert_local_object "$md_feature_oid" "31"
   354    refute_local_object "$txt_feature_oid" "30"
   355  
   356    master="$(git rev-parse refs/heads/master)"
   357    feature="$(git rev-parse refs/heads/my-feature)"
   358    remote="$(git rev-parse refs/remotes/origin/master)"
   359  
   360    master_attrs="$(git cat-file -p "$master:.gitattributes")"
   361    remote_attrs="$(git cat-file -p "$remote:.gitattributes")"
   362    feature_attrs="$(git cat-file -p "$feature:.gitattributes")"
   363  
   364    [ ! $(echo "$master_attrs" | grep -q "*.txt text !filter !merge !diff") ]
   365    [ ! $(echo "$remote_attrs" | grep -q "*.txt text !filter !merge !diff") ]
   366    echo "$feature_attrs" | grep -q "*.txt text !filter !merge !diff"
   367  )
   368  end_test
   369  
   370  begin_test "migrate export (--object-map)"
   371  (
   372    set -e
   373  
   374    setup_multiple_local_branches_tracked
   375  
   376    output_dir=$(mktemp -d)
   377  
   378    git log --all --pretty='format:%H' > "${output_dir}/old_sha.txt"
   379    git lfs migrate export --everything --include="*" --object-map "${output_dir}/object-map.txt"
   380    git log --all --pretty='format:%H' > "${output_dir}/new_sha.txt"
   381    paste -d',' "${output_dir}/old_sha.txt" "${output_dir}/new_sha.txt" > "${output_dir}/expected-map.txt"
   382  
   383    diff -u <(sort "${output_dir}/expected-map.txt") <(sort "${output_dir}/object-map.txt")
   384  )
   385  end_test
   386  
   387  begin_test "migrate export (--verbose)"
   388  (
   389    set -e
   390  
   391    setup_multiple_local_branches_tracked
   392  
   393    git lfs migrate export --everything --include="*" --verbose 2>&1 | grep -q "migrate: commit "
   394  )
   395  end_test
   396  
   397  begin_test "migrate export (--remote)"
   398  (
   399    set -e
   400  
   401    setup_single_remote_branch_tracked
   402  
   403    git push origin master
   404  
   405    md_oid="$(calc_oid "$(cat a.md)")"
   406    txt_oid="$(calc_oid "$(cat a.txt)")"
   407  
   408    assert_pointer "refs/heads/master" "a.md" "$md_oid" "50"
   409    assert_pointer "refs/heads/master" "a.txt" "$txt_oid" "30"
   410  
   411    # Flush the cache to ensure all objects have to be downloaded
   412    rm -rf .git/lfs/objects
   413  
   414    # Setup a new remote and invalidate the default
   415    remote_url="$(git config --get remote.origin.url)"
   416    git remote add zeta "$remote_url"
   417    git remote set-url origin ""
   418  
   419    git lfs migrate export --everything --remote="zeta" --include="*.md, *.txt"
   420  
   421    refute_pointer "refs/heads/master" "a.md"
   422    refute_pointer "refs/heads/master" "a.txt"
   423  
   424    refute_local_object "$md_oid" "50"
   425    refute_local_object "$txt_oid" "30"
   426  )
   427  end_test
   428  
   429  begin_test "migrate export (invalid --remote)"
   430  (
   431    set -e
   432  
   433    setup_single_remote_branch_tracked
   434  
   435    git lfs migrate export --include="*" --remote="zz" --yes 2>&1 \
   436      | tee migrate.log
   437    if [ ${PIPESTATUS[0]} -eq 0 ]; then
   438      echo >&2 "fatal: expected git lfs migrate export to fail, didn't"
   439      exit 1
   440    fi
   441  
   442    grep "fatal: invalid remote zz provided" migrate.log
   443  )
   444  end_test