Converting git repository to shallow?
up vote
39
down vote
favorite
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
add a comment |
up vote
39
down vote
favorite
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
stackoverflow.com/questions/1398919/… could help. What gives agit 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 involvinggit commit-tree
.
– MatrixFrog
Jan 20 '11 at 6:06
add a comment |
up vote
39
down vote
favorite
up vote
39
down vote
favorite
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
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
git
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 agit 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 involvinggit commit-tree
.
– MatrixFrog
Jan 20 '11 at 6:06
add a comment |
stackoverflow.com/questions/1398919/… could help. What gives agit 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 involvinggit 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
add a comment |
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
.
- Create a new empty branch
- Checkout the tree of the earliest commit you want to keep, without actually checking out the commit:
git checkout c0ffee -- .
(NowHEAD
is still pointing to your new empty branch, but your working tree and index both look like the tree ofc0ffee
) - Commit the whole tree:
git commit -m "Initial commit, copied from c0ffee"
- At this point
git diff-tree newbranch c0ffee
should produce no output -- they have the same tree. (Alternatively, you could dogit show -s c0ffee --format=%T
andgit show -s newbranch --format=%T
and they should show the same hash.) git rebase --onto newbranch c0ffee master
git branch -d newbranch
git gc
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 withgit clone --depth=n', and you wouldn't be able to undo it with git
fetch --unshallow'.
– Edward Anderson
Sep 1 '15 at 13:54
add a comment |
up vote
27
down vote
This worked for me:
git pull --depth 1
git gc --prune=all
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 andgit 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
|
show 2 more comments
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.
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 usegit describe --always HEAD~5
instead ofshow-ref -s HEAD
to keep the latest commits. Then there is alsogit 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 thatgit prune
performsgit 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
|
show 2 more comments
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
.
add a comment |
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 agit fetch --prune
(or even agit 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 teachgit 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.
add a comment |
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
.
- Create a new empty branch
- Checkout the tree of the earliest commit you want to keep, without actually checking out the commit:
git checkout c0ffee -- .
(NowHEAD
is still pointing to your new empty branch, but your working tree and index both look like the tree ofc0ffee
) - Commit the whole tree:
git commit -m "Initial commit, copied from c0ffee"
- At this point
git diff-tree newbranch c0ffee
should produce no output -- they have the same tree. (Alternatively, you could dogit show -s c0ffee --format=%T
andgit show -s newbranch --format=%T
and they should show the same hash.) git rebase --onto newbranch c0ffee master
git branch -d newbranch
git gc
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 withgit clone --depth=n', and you wouldn't be able to undo it with git
fetch --unshallow'.
– Edward Anderson
Sep 1 '15 at 13:54
add a comment |
up vote
-8
down vote
accepted
Let's say the earliest commit you want to keep has a SHA1 of c0ffee
.
- Create a new empty branch
- Checkout the tree of the earliest commit you want to keep, without actually checking out the commit:
git checkout c0ffee -- .
(NowHEAD
is still pointing to your new empty branch, but your working tree and index both look like the tree ofc0ffee
) - Commit the whole tree:
git commit -m "Initial commit, copied from c0ffee"
- At this point
git diff-tree newbranch c0ffee
should produce no output -- they have the same tree. (Alternatively, you could dogit show -s c0ffee --format=%T
andgit show -s newbranch --format=%T
and they should show the same hash.) git rebase --onto newbranch c0ffee master
git branch -d newbranch
git gc
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 withgit clone --depth=n', and you wouldn't be able to undo it with git
fetch --unshallow'.
– Edward Anderson
Sep 1 '15 at 13:54
add a comment |
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
.
- Create a new empty branch
- Checkout the tree of the earliest commit you want to keep, without actually checking out the commit:
git checkout c0ffee -- .
(NowHEAD
is still pointing to your new empty branch, but your working tree and index both look like the tree ofc0ffee
) - Commit the whole tree:
git commit -m "Initial commit, copied from c0ffee"
- At this point
git diff-tree newbranch c0ffee
should produce no output -- they have the same tree. (Alternatively, you could dogit show -s c0ffee --format=%T
andgit show -s newbranch --format=%T
and they should show the same hash.) git rebase --onto newbranch c0ffee master
git branch -d newbranch
git gc
Let's say the earliest commit you want to keep has a SHA1 of c0ffee
.
- Create a new empty branch
- Checkout the tree of the earliest commit you want to keep, without actually checking out the commit:
git checkout c0ffee -- .
(NowHEAD
is still pointing to your new empty branch, but your working tree and index both look like the tree ofc0ffee
) - Commit the whole tree:
git commit -m "Initial commit, copied from c0ffee"
- At this point
git diff-tree newbranch c0ffee
should produce no output -- they have the same tree. (Alternatively, you could dogit show -s c0ffee --format=%T
andgit show -s newbranch --format=%T
and they should show the same hash.) git rebase --onto newbranch c0ffee master
git branch -d newbranch
git gc
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 withgit clone --depth=n', and you wouldn't be able to undo it with git
fetch --unshallow'.
– Edward Anderson
Sep 1 '15 at 13:54
add a comment |
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 withgit 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
add a comment |
up vote
27
down vote
This worked for me:
git pull --depth 1
git gc --prune=all
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 andgit 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
|
show 2 more comments
up vote
27
down vote
This worked for me:
git pull --depth 1
git gc --prune=all
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 andgit 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
|
show 2 more comments
up vote
27
down vote
up vote
27
down vote
This worked for me:
git pull --depth 1
git gc --prune=all
This worked for me:
git pull --depth 1
git gc --prune=all
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 andgit 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
|
show 2 more comments
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 andgit 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
|
show 2 more comments
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.
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 usegit describe --always HEAD~5
instead ofshow-ref -s HEAD
to keep the latest commits. Then there is alsogit 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 thatgit prune
performsgit 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
|
show 2 more comments
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.
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 usegit describe --always HEAD~5
instead ofshow-ref -s HEAD
to keep the latest commits. Then there is alsogit 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 thatgit prune
performsgit 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
|
show 2 more comments
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.
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.
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 usegit describe --always HEAD~5
instead ofshow-ref -s HEAD
to keep the latest commits. Then there is alsogit 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 thatgit prune
performsgit 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
|
show 2 more comments
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 usegit describe --always HEAD~5
instead ofshow-ref -s HEAD
to keep the latest commits. Then there is alsogit 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 thatgit prune
performsgit 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
|
show 2 more comments
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
.
add a comment |
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
.
add a comment |
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
.
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
.
edited Oct 13 '17 at 8:01
answered Sep 24 '17 at 11:31
VasyaNovikov
4,94622236
4,94622236
add a comment |
add a comment |
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 agit fetch --prune
(or even agit 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 teachgit 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.
add a comment |
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 agit fetch --prune
(or even agit 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 teachgit 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.
add a comment |
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 agit fetch --prune
(or even agit 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 teachgit 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.
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 agit fetch --prune
(or even agit 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 teachgit 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.
answered Nov 11 at 2:04
VonC
823k28425853105
823k28425853105
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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