Converting git repository to shallow?











up vote
39
down vote

favorite
19












How can I convert an already cloned git repository to a shallow repository?



The git repository is downloaded through a script outside of my control so I cannot do a shallow clone.



The reason for doing this is to save disk space. (Yes, I'm really short on disk space so even though a shallow repository doesn't save much, it is needed.)



I already tried



git repack -a -d -f -depth=1


But that actually made the repository larger.










share|improve this question
























  • stackoverflow.com/questions/1398919/… could help. What gives a git gc after your repack?
    – VonC
    Jan 15 '11 at 9:20










  • huitseeker: Thanks for bringing it up. I am aware of the limitations and I am okay with it. I need access to the latest commit, or ideally couple of commits, but that's it.
    – Robert
    Jan 15 '11 at 11:44










  • VonC: I'm doing a gc --aggressive right now. I should gain some from it, but if possible I would also like to drop objects I don't need.
    – Robert
    Jan 15 '11 at 11:45










  • I just came across progit.org/2010/03/17/replace.html which suggests an alternate, potentially simpler, process involving git commit-tree.
    – MatrixFrog
    Jan 20 '11 at 6:06















up vote
39
down vote

favorite
19












How can I convert an already cloned git repository to a shallow repository?



The git repository is downloaded through a script outside of my control so I cannot do a shallow clone.



The reason for doing this is to save disk space. (Yes, I'm really short on disk space so even though a shallow repository doesn't save much, it is needed.)



I already tried



git repack -a -d -f -depth=1


But that actually made the repository larger.










share|improve this question
























  • stackoverflow.com/questions/1398919/… could help. What gives a git gc after your repack?
    – VonC
    Jan 15 '11 at 9:20










  • huitseeker: Thanks for bringing it up. I am aware of the limitations and I am okay with it. I need access to the latest commit, or ideally couple of commits, but that's it.
    – Robert
    Jan 15 '11 at 11:44










  • VonC: I'm doing a gc --aggressive right now. I should gain some from it, but if possible I would also like to drop objects I don't need.
    – Robert
    Jan 15 '11 at 11:45










  • I just came across progit.org/2010/03/17/replace.html which suggests an alternate, potentially simpler, process involving git commit-tree.
    – MatrixFrog
    Jan 20 '11 at 6:06













up vote
39
down vote

favorite
19









up vote
39
down vote

favorite
19






19





How can I convert an already cloned git repository to a shallow repository?



The git repository is downloaded through a script outside of my control so I cannot do a shallow clone.



The reason for doing this is to save disk space. (Yes, I'm really short on disk space so even though a shallow repository doesn't save much, it is needed.)



I already tried



git repack -a -d -f -depth=1


But that actually made the repository larger.










share|improve this question















How can I convert an already cloned git repository to a shallow repository?



The git repository is downloaded through a script outside of my control so I cannot do a shallow clone.



The reason for doing this is to save disk space. (Yes, I'm really short on disk space so even though a shallow repository doesn't save much, it is needed.)



I already tried



git repack -a -d -f -depth=1


But that actually made the repository larger.







git






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 15 '11 at 18:39









Philipp

36.6k107095




36.6k107095










asked Jan 15 '11 at 8:57









Robert

5,33932333




5,33932333












  • stackoverflow.com/questions/1398919/… could help. What gives a git gc after your repack?
    – VonC
    Jan 15 '11 at 9:20










  • huitseeker: Thanks for bringing it up. I am aware of the limitations and I am okay with it. I need access to the latest commit, or ideally couple of commits, but that's it.
    – Robert
    Jan 15 '11 at 11:44










  • VonC: I'm doing a gc --aggressive right now. I should gain some from it, but if possible I would also like to drop objects I don't need.
    – Robert
    Jan 15 '11 at 11:45










  • I just came across progit.org/2010/03/17/replace.html which suggests an alternate, potentially simpler, process involving git commit-tree.
    – MatrixFrog
    Jan 20 '11 at 6:06


















  • stackoverflow.com/questions/1398919/… could help. What gives a git gc after your repack?
    – VonC
    Jan 15 '11 at 9:20










  • huitseeker: Thanks for bringing it up. I am aware of the limitations and I am okay with it. I need access to the latest commit, or ideally couple of commits, but that's it.
    – Robert
    Jan 15 '11 at 11:44










  • VonC: I'm doing a gc --aggressive right now. I should gain some from it, but if possible I would also like to drop objects I don't need.
    – Robert
    Jan 15 '11 at 11:45










  • I just came across progit.org/2010/03/17/replace.html which suggests an alternate, potentially simpler, process involving git commit-tree.
    – MatrixFrog
    Jan 20 '11 at 6:06
















stackoverflow.com/questions/1398919/… could help. What gives a git gc after your repack?
– VonC
Jan 15 '11 at 9:20




stackoverflow.com/questions/1398919/… could help. What gives a git gc after your repack?
– VonC
Jan 15 '11 at 9:20












huitseeker: Thanks for bringing it up. I am aware of the limitations and I am okay with it. I need access to the latest commit, or ideally couple of commits, but that's it.
– Robert
Jan 15 '11 at 11:44




huitseeker: Thanks for bringing it up. I am aware of the limitations and I am okay with it. I need access to the latest commit, or ideally couple of commits, but that's it.
– Robert
Jan 15 '11 at 11:44












VonC: I'm doing a gc --aggressive right now. I should gain some from it, but if possible I would also like to drop objects I don't need.
– Robert
Jan 15 '11 at 11:45




VonC: I'm doing a gc --aggressive right now. I should gain some from it, but if possible I would also like to drop objects I don't need.
– Robert
Jan 15 '11 at 11:45












I just came across progit.org/2010/03/17/replace.html which suggests an alternate, potentially simpler, process involving git commit-tree.
– MatrixFrog
Jan 20 '11 at 6:06




I just came across progit.org/2010/03/17/replace.html which suggests an alternate, potentially simpler, process involving git commit-tree.
– MatrixFrog
Jan 20 '11 at 6:06












5 Answers
5






active

oldest

votes

















up vote
-8
down vote



accepted










Let's say the earliest commit you want to keep has a SHA1 of c0ffee.




  1. Create a new empty branch

  2. Checkout the tree of the earliest commit you want to keep, without actually checking out the commit: git checkout c0ffee -- . (Now HEAD is still pointing to your new empty branch, but your working tree and index both look like the tree of c0ffee)

  3. Commit the whole tree: git commit -m "Initial commit, copied from c0ffee"

  4. At this point git diff-tree newbranch c0ffee should produce no output -- they have the same tree. (Alternatively, you could do git show -s c0ffee --format=%T and git show -s newbranch --format=%T and they should show the same hash.)

  5. git rebase --onto newbranch c0ffee master

  6. git branch -d newbranch

  7. git gc






share|improve this answer























  • Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
    – Robert
    Jan 16 '11 at 9:16






  • 6




    This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
    – Edward Anderson
    Sep 1 '15 at 13:54


















up vote
27
down vote













This worked for me:



git pull --depth 1
git gc --prune=all





share|improve this answer























  • Exceptionally simple and straightforward. Love it.
    – tzrlk
    Nov 19 '16 at 4:25










  • Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
    – Ben Farmer
    Jan 16 '17 at 10:15










  • @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
    – fuzzyTew
    Jan 17 '17 at 1:28












  • hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
    – Ben Farmer
    Jan 18 '17 at 9:02






  • 6




    I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
    – Dzmitry
    Apr 5 '17 at 8:57




















up vote
11
down vote













You can convert git repo to a shallow one in place along this lines:



git show-ref -s HEAD > .git/shallow
git reflog expire --expire=0
git prune
git prune-packed


Make sure to make backup since this is destructive operation, also keep in mind that cloning nor fetching from shallow repo is not supported! To really remove all the history you also need to remove all references to previous commits before pruning.






share|improve this answer

















  • 5




    Actually this doesn't seem to do anything.
    – hendry
    May 1 '12 at 5:04










  • hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
    – user212328
    Jun 3 '12 at 11:47










  • For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
    – blueyed
    Mar 27 '14 at 9:05






  • 2




    In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
    – Jiyong Park
    Mar 1 '16 at 2:11








  • 1




    Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
    – fuzzyTew
    May 31 '16 at 1:19


















up vote
2
down vote













Solution:



git clone --depth 1 file:///full/path/to/original/dir destination


Note that the first "address" should be a file://, that's important. Also, git will assume your original local file:// address to be the "remote" ("origin"), so you'll need to update the new repository specifying the correct git remote.






share|improve this answer






























    up vote
    1
    down vote













    Note that a shallow repo (like one with git clone --depth 1 as a way to convert an existing repo to a shallow one) can fail on git repack.



    See commit 5dcfbf5, commit 2588f6e, commit 328a435 (24 Oct 2018) by Johannes Schindelin (dscho).
    (Merged by Junio C Hamano -- gitster -- in commit ea100b6, 06 Nov 2018)




    repack -ad: prune the list of shallow commits



    git repack can drop unreachable commits without further warning,
    making the corresponding entries in .git/shallow invalid, which causes
    serious problems when deepening the branches.



    One scenario where unreachable commits are dropped by git repack is
    when a git fetch --prune (or even a git fetch when a ref was
    force-pushed in the meantime) can make a commit unreachable that was
    reachable before.



    Therefore it is not safe to assume that a git repack -adlf will keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).



    This is particularly important to keep in mind when looking at the
    .git/shallow file: if any commits listed in that file become
    unreachable, it is not a problem, but if they go missing, it is a
    problem.

    One symptom of this problem is that a deepening fetch may now
    fail with:



    fatal: error in object: unshallow <commit-hash>


    To avoid this problem, let's prune the shallow list in git repack when the -d option is passed, unless -A is passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).

    Additionally, we also need to take --keep-reachable and --unpack-unreachable=<date> into account.



    Note: an alternative solution discussed during the review of this patch
    was to teach git fetch to simply ignore entries in .git/shallow if the
    corresponding commits do not exist locally.

    A quick test, however, revealed that the .git/shallow file is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line
    does need to be sent.

    Therefore, this approach would be a lot more finicky than the approach presented by the this patch.







    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4698759%2fconverting-git-repository-to-shallow%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      -8
      down vote



      accepted










      Let's say the earliest commit you want to keep has a SHA1 of c0ffee.




      1. Create a new empty branch

      2. Checkout the tree of the earliest commit you want to keep, without actually checking out the commit: git checkout c0ffee -- . (Now HEAD is still pointing to your new empty branch, but your working tree and index both look like the tree of c0ffee)

      3. Commit the whole tree: git commit -m "Initial commit, copied from c0ffee"

      4. At this point git diff-tree newbranch c0ffee should produce no output -- they have the same tree. (Alternatively, you could do git show -s c0ffee --format=%T and git show -s newbranch --format=%T and they should show the same hash.)

      5. git rebase --onto newbranch c0ffee master

      6. git branch -d newbranch

      7. git gc






      share|improve this answer























      • Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
        – Robert
        Jan 16 '11 at 9:16






      • 6




        This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
        – Edward Anderson
        Sep 1 '15 at 13:54















      up vote
      -8
      down vote



      accepted










      Let's say the earliest commit you want to keep has a SHA1 of c0ffee.




      1. Create a new empty branch

      2. Checkout the tree of the earliest commit you want to keep, without actually checking out the commit: git checkout c0ffee -- . (Now HEAD is still pointing to your new empty branch, but your working tree and index both look like the tree of c0ffee)

      3. Commit the whole tree: git commit -m "Initial commit, copied from c0ffee"

      4. At this point git diff-tree newbranch c0ffee should produce no output -- they have the same tree. (Alternatively, you could do git show -s c0ffee --format=%T and git show -s newbranch --format=%T and they should show the same hash.)

      5. git rebase --onto newbranch c0ffee master

      6. git branch -d newbranch

      7. git gc






      share|improve this answer























      • Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
        – Robert
        Jan 16 '11 at 9:16






      • 6




        This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
        – Edward Anderson
        Sep 1 '15 at 13:54













      up vote
      -8
      down vote



      accepted







      up vote
      -8
      down vote



      accepted






      Let's say the earliest commit you want to keep has a SHA1 of c0ffee.




      1. Create a new empty branch

      2. Checkout the tree of the earliest commit you want to keep, without actually checking out the commit: git checkout c0ffee -- . (Now HEAD is still pointing to your new empty branch, but your working tree and index both look like the tree of c0ffee)

      3. Commit the whole tree: git commit -m "Initial commit, copied from c0ffee"

      4. At this point git diff-tree newbranch c0ffee should produce no output -- they have the same tree. (Alternatively, you could do git show -s c0ffee --format=%T and git show -s newbranch --format=%T and they should show the same hash.)

      5. git rebase --onto newbranch c0ffee master

      6. git branch -d newbranch

      7. git gc






      share|improve this answer














      Let's say the earliest commit you want to keep has a SHA1 of c0ffee.




      1. Create a new empty branch

      2. Checkout the tree of the earliest commit you want to keep, without actually checking out the commit: git checkout c0ffee -- . (Now HEAD is still pointing to your new empty branch, but your working tree and index both look like the tree of c0ffee)

      3. Commit the whole tree: git commit -m "Initial commit, copied from c0ffee"

      4. At this point git diff-tree newbranch c0ffee should produce no output -- they have the same tree. (Alternatively, you could do git show -s c0ffee --format=%T and git show -s newbranch --format=%T and they should show the same hash.)

      5. git rebase --onto newbranch c0ffee master

      6. git branch -d newbranch

      7. git gc







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 15 '11 at 18:21

























      answered Jan 15 '11 at 18:05









      MatrixFrog

      16.1k95084




      16.1k95084












      • Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
        – Robert
        Jan 16 '11 at 9:16






      • 6




        This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
        – Edward Anderson
        Sep 1 '15 at 13:54


















      • Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
        – Robert
        Jan 16 '11 at 9:16






      • 6




        This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
        – Edward Anderson
        Sep 1 '15 at 13:54
















      Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
      – Robert
      Jan 16 '11 at 9:16




      Thank you! This was exactly what I needed. Now, if I could only understand why feel the urge for a coffee?
      – Robert
      Jan 16 '11 at 9:16




      6




      6




      This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
      – Edward Anderson
      Sep 1 '15 at 13:54




      This does not convert the repository to shallow as a shallow clone would with git clone --depth=n', and you wouldn't be able to undo it with git fetch --unshallow'.
      – Edward Anderson
      Sep 1 '15 at 13:54












      up vote
      27
      down vote













      This worked for me:



      git pull --depth 1
      git gc --prune=all





      share|improve this answer























      • Exceptionally simple and straightforward. Love it.
        – tzrlk
        Nov 19 '16 at 4:25










      • Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
        – Ben Farmer
        Jan 16 '17 at 10:15










      • @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
        – fuzzyTew
        Jan 17 '17 at 1:28












      • hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
        – Ben Farmer
        Jan 18 '17 at 9:02






      • 6




        I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
        – Dzmitry
        Apr 5 '17 at 8:57

















      up vote
      27
      down vote













      This worked for me:



      git pull --depth 1
      git gc --prune=all





      share|improve this answer























      • Exceptionally simple and straightforward. Love it.
        – tzrlk
        Nov 19 '16 at 4:25










      • Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
        – Ben Farmer
        Jan 16 '17 at 10:15










      • @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
        – fuzzyTew
        Jan 17 '17 at 1:28












      • hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
        – Ben Farmer
        Jan 18 '17 at 9:02






      • 6




        I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
        – Dzmitry
        Apr 5 '17 at 8:57















      up vote
      27
      down vote










      up vote
      27
      down vote









      This worked for me:



      git pull --depth 1
      git gc --prune=all





      share|improve this answer














      This worked for me:



      git pull --depth 1
      git gc --prune=all






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Feb 7 at 3:17

























      answered Nov 6 '16 at 18:04









      fuzzyTew

      1,8011717




      1,8011717












      • Exceptionally simple and straightforward. Love it.
        – tzrlk
        Nov 19 '16 at 4:25










      • Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
        – Ben Farmer
        Jan 16 '17 at 10:15










      • @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
        – fuzzyTew
        Jan 17 '17 at 1:28












      • hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
        – Ben Farmer
        Jan 18 '17 at 9:02






      • 6




        I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
        – Dzmitry
        Apr 5 '17 at 8:57




















      • Exceptionally simple and straightforward. Love it.
        – tzrlk
        Nov 19 '16 at 4:25










      • Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
        – Ben Farmer
        Jan 16 '17 at 10:15










      • @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
        – fuzzyTew
        Jan 17 '17 at 1:28












      • hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
        – Ben Farmer
        Jan 18 '17 at 9:02






      • 6




        I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
        – Dzmitry
        Apr 5 '17 at 8:57


















      Exceptionally simple and straightforward. Love it.
      – tzrlk
      Nov 19 '16 at 4:25




      Exceptionally simple and straightforward. Love it.
      – tzrlk
      Nov 19 '16 at 4:25












      Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
      – Ben Farmer
      Jan 16 '17 at 10:15




      Hmm for me this gives "fatal: git fetch-pack: expected shallow list" on the pull.
      – Ben Farmer
      Jan 16 '17 at 10:15












      @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
      – fuzzyTew
      Jan 17 '17 at 1:28






      @BenFarmer Well that's no good! As shallow support has been slowly developing, this probably only works on recent versions of git. What version do you have?
      – fuzzyTew
      Jan 17 '17 at 1:28














      hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
      – Ben Farmer
      Jan 18 '17 at 9:02




      hmm, seems to be 2.7.0.rc3. I'll see if a newer one is available in my repos and try that...
      – Ben Farmer
      Jan 18 '17 at 9:02




      6




      6




      I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
      – Dzmitry
      Apr 5 '17 at 8:57






      I've run the above commands. The repo is indeed shallow now (git log shows only one commit and git branch shows just one branch). But the .git folder still occupies 2.5 GB. The same repo cloned with --depth 1 occupies about 1 GB. Any advice how to cut down the disk usage?
      – Dzmitry
      Apr 5 '17 at 8:57












      up vote
      11
      down vote













      You can convert git repo to a shallow one in place along this lines:



      git show-ref -s HEAD > .git/shallow
      git reflog expire --expire=0
      git prune
      git prune-packed


      Make sure to make backup since this is destructive operation, also keep in mind that cloning nor fetching from shallow repo is not supported! To really remove all the history you also need to remove all references to previous commits before pruning.






      share|improve this answer

















      • 5




        Actually this doesn't seem to do anything.
        – hendry
        May 1 '12 at 5:04










      • hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
        – user212328
        Jun 3 '12 at 11:47










      • For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
        – blueyed
        Mar 27 '14 at 9:05






      • 2




        In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
        – Jiyong Park
        Mar 1 '16 at 2:11








      • 1




        Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
        – fuzzyTew
        May 31 '16 at 1:19















      up vote
      11
      down vote













      You can convert git repo to a shallow one in place along this lines:



      git show-ref -s HEAD > .git/shallow
      git reflog expire --expire=0
      git prune
      git prune-packed


      Make sure to make backup since this is destructive operation, also keep in mind that cloning nor fetching from shallow repo is not supported! To really remove all the history you also need to remove all references to previous commits before pruning.






      share|improve this answer

















      • 5




        Actually this doesn't seem to do anything.
        – hendry
        May 1 '12 at 5:04










      • hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
        – user212328
        Jun 3 '12 at 11:47










      • For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
        – blueyed
        Mar 27 '14 at 9:05






      • 2




        In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
        – Jiyong Park
        Mar 1 '16 at 2:11








      • 1




        Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
        – fuzzyTew
        May 31 '16 at 1:19













      up vote
      11
      down vote










      up vote
      11
      down vote









      You can convert git repo to a shallow one in place along this lines:



      git show-ref -s HEAD > .git/shallow
      git reflog expire --expire=0
      git prune
      git prune-packed


      Make sure to make backup since this is destructive operation, also keep in mind that cloning nor fetching from shallow repo is not supported! To really remove all the history you also need to remove all references to previous commits before pruning.






      share|improve this answer












      You can convert git repo to a shallow one in place along this lines:



      git show-ref -s HEAD > .git/shallow
      git reflog expire --expire=0
      git prune
      git prune-packed


      Make sure to make backup since this is destructive operation, also keep in mind that cloning nor fetching from shallow repo is not supported! To really remove all the history you also need to remove all references to previous commits before pruning.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Oct 29 '11 at 9:02









      user212328

      49457




      49457








      • 5




        Actually this doesn't seem to do anything.
        – hendry
        May 1 '12 at 5:04










      • hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
        – user212328
        Jun 3 '12 at 11:47










      • For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
        – blueyed
        Mar 27 '14 at 9:05






      • 2




        In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
        – Jiyong Park
        Mar 1 '16 at 2:11








      • 1




        Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
        – fuzzyTew
        May 31 '16 at 1:19














      • 5




        Actually this doesn't seem to do anything.
        – hendry
        May 1 '12 at 5:04










      • hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
        – user212328
        Jun 3 '12 at 11:47










      • For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
        – blueyed
        Mar 27 '14 at 9:05






      • 2




        In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
        – Jiyong Park
        Mar 1 '16 at 2:11








      • 1




        Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
        – fuzzyTew
        May 31 '16 at 1:19








      5




      5




      Actually this doesn't seem to do anything.
      – hendry
      May 1 '12 at 5:04




      Actually this doesn't seem to do anything.
      – hendry
      May 1 '12 at 5:04












      hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
      – user212328
      Jun 3 '12 at 11:47




      hendry: Most likely you have not removed other references pointing to HEAD's history. Try removing all other branches and tags before attempting this steps.
      – user212328
      Jun 3 '12 at 11:47












      For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
      – blueyed
      Mar 27 '14 at 9:05




      For submodules, you might need to resolve the .git file to the git dir (git rev-parse --git-dir). Also, you could use git describe --always HEAD~5 instead of show-ref -s HEAD to keep the latest commits. Then there is also git fetch --unshallow in the meantime to unshallow a clone.
      – blueyed
      Mar 27 '14 at 9:05




      2




      2




      In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
      – Jiyong Park
      Mar 1 '16 at 2:11






      In order to remove all references, add --all to the reflog command: git reflog expire --expire=now --all
      – Jiyong Park
      Mar 1 '16 at 2:11






      1




      1




      Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
      – fuzzyTew
      May 31 '16 at 1:19




      Note that git prune performs git prune-packed already. Also note that if you want all branches stored, they must all have their tips listed in .git/shallow. This command worked for me, but I don't know if it will work all the time: find .git/refs -type f | xargs cat | sort -u > .git/shallow
      – fuzzyTew
      May 31 '16 at 1:19










      up vote
      2
      down vote













      Solution:



      git clone --depth 1 file:///full/path/to/original/dir destination


      Note that the first "address" should be a file://, that's important. Also, git will assume your original local file:// address to be the "remote" ("origin"), so you'll need to update the new repository specifying the correct git remote.






      share|improve this answer



























        up vote
        2
        down vote













        Solution:



        git clone --depth 1 file:///full/path/to/original/dir destination


        Note that the first "address" should be a file://, that's important. Also, git will assume your original local file:// address to be the "remote" ("origin"), so you'll need to update the new repository specifying the correct git remote.






        share|improve this answer

























          up vote
          2
          down vote










          up vote
          2
          down vote









          Solution:



          git clone --depth 1 file:///full/path/to/original/dir destination


          Note that the first "address" should be a file://, that's important. Also, git will assume your original local file:// address to be the "remote" ("origin"), so you'll need to update the new repository specifying the correct git remote.






          share|improve this answer














          Solution:



          git clone --depth 1 file:///full/path/to/original/dir destination


          Note that the first "address" should be a file://, that's important. Also, git will assume your original local file:// address to be the "remote" ("origin"), so you'll need to update the new repository specifying the correct git remote.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 13 '17 at 8:01

























          answered Sep 24 '17 at 11:31









          VasyaNovikov

          4,94622236




          4,94622236






















              up vote
              1
              down vote













              Note that a shallow repo (like one with git clone --depth 1 as a way to convert an existing repo to a shallow one) can fail on git repack.



              See commit 5dcfbf5, commit 2588f6e, commit 328a435 (24 Oct 2018) by Johannes Schindelin (dscho).
              (Merged by Junio C Hamano -- gitster -- in commit ea100b6, 06 Nov 2018)




              repack -ad: prune the list of shallow commits



              git repack can drop unreachable commits without further warning,
              making the corresponding entries in .git/shallow invalid, which causes
              serious problems when deepening the branches.



              One scenario where unreachable commits are dropped by git repack is
              when a git fetch --prune (or even a git fetch when a ref was
              force-pushed in the meantime) can make a commit unreachable that was
              reachable before.



              Therefore it is not safe to assume that a git repack -adlf will keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).



              This is particularly important to keep in mind when looking at the
              .git/shallow file: if any commits listed in that file become
              unreachable, it is not a problem, but if they go missing, it is a
              problem.

              One symptom of this problem is that a deepening fetch may now
              fail with:



              fatal: error in object: unshallow <commit-hash>


              To avoid this problem, let's prune the shallow list in git repack when the -d option is passed, unless -A is passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).

              Additionally, we also need to take --keep-reachable and --unpack-unreachable=<date> into account.



              Note: an alternative solution discussed during the review of this patch
              was to teach git fetch to simply ignore entries in .git/shallow if the
              corresponding commits do not exist locally.

              A quick test, however, revealed that the .git/shallow file is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line
              does need to be sent.

              Therefore, this approach would be a lot more finicky than the approach presented by the this patch.







              share|improve this answer

























                up vote
                1
                down vote













                Note that a shallow repo (like one with git clone --depth 1 as a way to convert an existing repo to a shallow one) can fail on git repack.



                See commit 5dcfbf5, commit 2588f6e, commit 328a435 (24 Oct 2018) by Johannes Schindelin (dscho).
                (Merged by Junio C Hamano -- gitster -- in commit ea100b6, 06 Nov 2018)




                repack -ad: prune the list of shallow commits



                git repack can drop unreachable commits without further warning,
                making the corresponding entries in .git/shallow invalid, which causes
                serious problems when deepening the branches.



                One scenario where unreachable commits are dropped by git repack is
                when a git fetch --prune (or even a git fetch when a ref was
                force-pushed in the meantime) can make a commit unreachable that was
                reachable before.



                Therefore it is not safe to assume that a git repack -adlf will keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).



                This is particularly important to keep in mind when looking at the
                .git/shallow file: if any commits listed in that file become
                unreachable, it is not a problem, but if they go missing, it is a
                problem.

                One symptom of this problem is that a deepening fetch may now
                fail with:



                fatal: error in object: unshallow <commit-hash>


                To avoid this problem, let's prune the shallow list in git repack when the -d option is passed, unless -A is passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).

                Additionally, we also need to take --keep-reachable and --unpack-unreachable=<date> into account.



                Note: an alternative solution discussed during the review of this patch
                was to teach git fetch to simply ignore entries in .git/shallow if the
                corresponding commits do not exist locally.

                A quick test, however, revealed that the .git/shallow file is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line
                does need to be sent.

                Therefore, this approach would be a lot more finicky than the approach presented by the this patch.







                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Note that a shallow repo (like one with git clone --depth 1 as a way to convert an existing repo to a shallow one) can fail on git repack.



                  See commit 5dcfbf5, commit 2588f6e, commit 328a435 (24 Oct 2018) by Johannes Schindelin (dscho).
                  (Merged by Junio C Hamano -- gitster -- in commit ea100b6, 06 Nov 2018)




                  repack -ad: prune the list of shallow commits



                  git repack can drop unreachable commits without further warning,
                  making the corresponding entries in .git/shallow invalid, which causes
                  serious problems when deepening the branches.



                  One scenario where unreachable commits are dropped by git repack is
                  when a git fetch --prune (or even a git fetch when a ref was
                  force-pushed in the meantime) can make a commit unreachable that was
                  reachable before.



                  Therefore it is not safe to assume that a git repack -adlf will keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).



                  This is particularly important to keep in mind when looking at the
                  .git/shallow file: if any commits listed in that file become
                  unreachable, it is not a problem, but if they go missing, it is a
                  problem.

                  One symptom of this problem is that a deepening fetch may now
                  fail with:



                  fatal: error in object: unshallow <commit-hash>


                  To avoid this problem, let's prune the shallow list in git repack when the -d option is passed, unless -A is passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).

                  Additionally, we also need to take --keep-reachable and --unpack-unreachable=<date> into account.



                  Note: an alternative solution discussed during the review of this patch
                  was to teach git fetch to simply ignore entries in .git/shallow if the
                  corresponding commits do not exist locally.

                  A quick test, however, revealed that the .git/shallow file is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line
                  does need to be sent.

                  Therefore, this approach would be a lot more finicky than the approach presented by the this patch.







                  share|improve this answer












                  Note that a shallow repo (like one with git clone --depth 1 as a way to convert an existing repo to a shallow one) can fail on git repack.



                  See commit 5dcfbf5, commit 2588f6e, commit 328a435 (24 Oct 2018) by Johannes Schindelin (dscho).
                  (Merged by Junio C Hamano -- gitster -- in commit ea100b6, 06 Nov 2018)




                  repack -ad: prune the list of shallow commits



                  git repack can drop unreachable commits without further warning,
                  making the corresponding entries in .git/shallow invalid, which causes
                  serious problems when deepening the branches.



                  One scenario where unreachable commits are dropped by git repack is
                  when a git fetch --prune (or even a git fetch when a ref was
                  force-pushed in the meantime) can make a commit unreachable that was
                  reachable before.



                  Therefore it is not safe to assume that a git repack -adlf will keep unreachable commits alone (under the assumption that they had not been packed in the first place, which is an assumption at least some of Git's code seems to make).



                  This is particularly important to keep in mind when looking at the
                  .git/shallow file: if any commits listed in that file become
                  unreachable, it is not a problem, but if they go missing, it is a
                  problem.

                  One symptom of this problem is that a deepening fetch may now
                  fail with:



                  fatal: error in object: unshallow <commit-hash>


                  To avoid this problem, let's prune the shallow list in git repack when the -d option is passed, unless -A is passed, too (which would force the now-unreachable objects to be turned into loose objects instead of being deleted).

                  Additionally, we also need to take --keep-reachable and --unpack-unreachable=<date> into account.



                  Note: an alternative solution discussed during the review of this patch
                  was to teach git fetch to simply ignore entries in .git/shallow if the
                  corresponding commits do not exist locally.

                  A quick test, however, revealed that the .git/shallow file is written during a shallow clone, in which case the commits do not exist, either, but the "shallow" line
                  does need to be sent.

                  Therefore, this approach would be a lot more finicky than the approach presented by the this patch.








                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 11 at 2:04









                  VonC

                  823k28425853105




                  823k28425853105






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4698759%2fconverting-git-repository-to-shallow%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Danny Elfman

                      Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues