How to NOT commit locally deleted files to git

后端 未结 4 1444
醉梦人生
醉梦人生 2021-01-22 18:33

We have a situation where were are using git to stash myriad scans (images) and do not wish to preserve them on the local machine once set on up; however, git is seeing each loc

相关标签:
4条回答
  • 2021-01-22 19:20

    Use the Skip-Worktree Bit

    The git-update-index(1) command provides some ways of dealing with this. Based on the assumption that you want to keep the blobs in your history while deleting them from your working tree, you could use the following:

    git add --all
    git commit --message="Add new assets to repository."
    git update-index update-index --skip-worktree <files ...>
    rm <files ...>
    

    Note that the last line isn't a Git command because you're removing the files from the working tree in the shell after you've stored them in the index. Don't use git rm by mistake, because it operates on the index.

    Listing Your Special Bits and Index-Only Files

    To see the files you've marked with the skip-worktree bit:

    git ls-files -v | awk -v IGNORECASE=1 '$1 ~ /s/ {print}'
    

    You can also use git-ls-files(1) to find files in the index that have been removed from your working tree.

    0 讨论(0)
  • 2021-01-22 19:24

    Just add images to gitignore. You do not need to store them in repo, right?

    0 讨论(0)
  • 2021-01-22 19:25

    For each file to be deleted, do this:

    git update-index --assume-unchanged <file>
    

    This should stop Git from asking you to commit the deletion.

    That being said, perhaps a better solution would be to use SFTP with permissions set to disallow deleting or modifying files once uploaded.

    0 讨论(0)
  • 2021-01-22 19:36

    (edit: package up the payload as a self-contained script)

    You're after a nearly status-only local repository that tracks the existence of everything you've ever created but keeps the contents of only the most recent stuff (after pushing everything upstream). Presuming you never reuse a pathname, here's the ritual:

    One-time setup:

    Create and push an everything branch that tracks every image you've got so far. Base a (local-only) worktree branch off that.

    git checkout -b everything     # this will be the branch you push
    git push origin everything     # .
    git checkout -b worktree       # you'll stay on this branch
    

    Work (almost) as if you didn't want to do anything special:

    Everything that needs preserving upstream is on the everything branch, and you've got worktree checked out. Remove images you're done with from the worktree, make new images there that need pushing, and commit the new worktree state:

    # work work:
    rm -r anything/ you\'re/ done with
    create new images
    git add -A .  # good gitignore patterns make life easy
    git commit
    

    To do the requested work, run

    merge-push-and-cleanup   # the script below
    

    After which everything's stored upstream, nothing redundant remains locally, and you're ready for more work.


    The merge-push-and-cleanup script:

    #!/bin/sh
    # Git can do "index-only" merges when the content doesn't need to be examined,
    # you can casually create sideband indexes, and `git commit-tree` works on any 
    # tree in the repo.
    
      (
    # ^ subshell to keep G_I_F export local
      export GIT_INDEX_FILE=.git/sideband-index
    
      # make a merged index that includes everything from both branches, by
      # starting from an empty merge base so all files show up as additions.
    
      git read-tree -im $(git mktree </dev/null) worktree everything
    
      # commit to the `everything` branch straight from the constructed index,
      # reusing the commit message from `worktree`
    
      git cat-file -p worktree | sed 1,/^$/d \
      | git commit-tree -p everything -p worktree $(git write-tree --missing-ok) \
      | xargs git update-ref refs/heads/everything
    )
    
    git push origin everything
    
    # preserve the branch metadata and, just for safety, your latest images
    # by packing it all up:
    
    mkdir -p .git/preserved/pack
    rm -f .git/preserved/pack/*
    (
      git rev-list worktree everything
      git rev-parse worktree^{tree} everything^{tree}
      git ls-tree -rt worktree | awk '{ print $3 }'
      git ls-tree -rt everything | awk '$2 != "blob" { print $3 }'
    ) \
    | git pack-objects .git/preserved/pack/pack
    
    # now for the fun one:
    rm -rf .git/objects/*   # !!!
    
    # put the preserved stuff back:
    mv .git/preserved/pack .git/objects
    
    0 讨论(0)
提交回复
热议问题