Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
git-backup
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
3
Issues
3
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
git-backup
Commits
cbfa78d2
Commit
cbfa78d2
authored
Jun 08, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*: Handle Git object types as git.ObjectType instead of string
parent
7f349cd9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
74 additions
and
17 deletions
+74
-17
git-backup.go
git-backup.go
+22
-13
git-backup_test.go
git-backup_test.go
+10
-1
gitobjects.go
gitobjects.go
+42
-3
No files found.
git-backup.go
View file @
cbfa78d2
...
...
@@ -184,20 +184,22 @@ func blob_to_file(g *git.Repository, blob_sha1 Sha1, mode uint32, path string) {
// another, so that on backup restore we only have to recreate original tag
// object and tagged object is kept there in repo thanks to it being reachable
// through created commit.
var
tag_tree_blob
=
StrSet
{
"tag"
:
{},
"tree"
:
{},
"blob"
:
{}}
func
obj_represent_as_commit
(
g
*
git
.
Repository
,
sha1
Sha1
,
obj_type
string
)
Sha1
{
if
!
tag_tree_blob
.
Contains
(
obj_type
)
{
func
obj_represent_as_commit
(
g
*
git
.
Repository
,
sha1
Sha1
,
obj_type
git
.
ObjectType
)
Sha1
{
switch
obj_type
{
case
git
.
ObjectTag
,
git
.
ObjectTree
,
git
.
ObjectBlob
:
// ok
default
:
exc
.
Raisef
(
"%s (%s): cannot encode as commit"
,
sha1
,
obj_type
)
}
// first line in commit msg = object type
obj_encoded
:=
obj_type
+
"
\n
"
var
tagged_type
string
obj_encoded
:=
gittypestr
(
obj_type
)
+
"
\n
"
var
tagged_type
git
.
ObjectType
var
tagged_sha1
Sha1
// below the code layout is mainly for tag type, and we hook tree and blob
// types handling into that layout
if
obj_type
==
"tag"
{
if
obj_type
==
git
.
ObjectTag
{
tag
,
tag_obj
:=
xload_tag
(
g
,
sha1
)
tagged_type
=
tag
.
tagged_type
tagged_sha1
=
tag
.
tagged_sha1
...
...
@@ -219,7 +221,7 @@ func obj_represent_as_commit(g *git.Repository, sha1 Sha1, obj_type string) Sha1
// | .msg: Tag
// v .tree -> ø
// Commit .parent -> Commit
if
tagged_type
==
"commit"
{
if
tagged_type
==
git
.
ObjectCommit
{
return
zcommit_tree
(
mktree_empty
(),
[]
Sha1
{
tagged_sha1
},
obj_encoded
)
}
...
...
@@ -227,7 +229,7 @@ func obj_represent_as_commit(g *git.Repository, sha1 Sha1, obj_type string) Sha1
// | .msg: Tag
// v .tree -> Tree
// Tree .parent -> ø
if
tagged_type
==
"tree"
{
if
tagged_type
==
git
.
ObjectTree
{
return
zcommit_tree
(
tagged_sha1
,
[]
Sha1
{},
obj_encoded
)
}
...
...
@@ -235,7 +237,7 @@ func obj_represent_as_commit(g *git.Repository, sha1 Sha1, obj_type string) Sha1
// | .msg: Tag
// v .tree -> Tree* "tagged" -> Blob
// Blob .parent -> ø
if
tagged_type
==
"blob"
{
if
tagged_type
==
git
.
ObjectBlob
{
tree_for_blob
:=
xgitSha1
(
"mktree"
,
RunWith
{
stdin
:
fmt
.
Sprintf
(
"100644 blob %s
\t
tagged
\n
"
,
tagged_sha1
)})
return
zcommit_tree
(
tree_for_blob
,
[]
Sha1
{},
obj_encoded
)
}
...
...
@@ -244,7 +246,7 @@ func obj_represent_as_commit(g *git.Repository, sha1 Sha1, obj_type string) Sha1
// | .msg: Tag₂
// v .tree -> ø
// Tag₁ .parent -> Commit₁*
if
tagged_type
==
"tag"
{
if
tagged_type
==
git
.
ObjectTag
{
commit1
:=
obj_represent_as_commit
(
g
,
tagged_sha1
,
tagged_type
)
return
zcommit_tree
(
mktree_empty
(),
[]
Sha1
{
commit1
},
obj_encoded
)
}
...
...
@@ -274,7 +276,10 @@ func obj_recreate_from_commit(g *git.Repository, commit_sha1 Sha1) Sha1 {
if
err
!=
nil
{
xraise
(
"invalid encoded format"
)
}
if
!
tag_tree_blob
.
Contains
(
obj_type
)
{
switch
obj_type
{
case
"tag"
,
"tree"
,
"blob"
:
// ok
default
:
xraisef
(
"unexpected encoded object type %q"
,
obj_type
)
}
...
...
@@ -295,7 +300,7 @@ func obj_recreate_from_commit(g *git.Repository, commit_sha1 Sha1) Sha1 {
if
err
!=
nil
{
xraisef
(
"encoded tag: %s"
,
err
)
}
if
tag
.
tagged_type
==
"tag"
{
if
tag
.
tagged_type
==
git
.
ObjectTag
{
if
commit
.
ParentCount
()
==
0
{
xraise
(
"encoded tag corrupt (tagged is tag but []parent is empty)"
)
}
...
...
@@ -494,7 +499,11 @@ func cmd_pull_(gb *git.Repository, pullspecv []PullSpec) {
var
seen
bool
sha1_
,
seen
=
noncommit_seen
[
sha1
]
if
!
seen
{
sha1_
=
obj_represent_as_commit
(
gb
,
sha1
,
type_
)
obj_type
,
ok
:=
gittype
(
type_
)
if
!
ok
{
exc
.
Raisef
(
"%s: invalid git type in entry %q"
,
backup_refs_work
,
__
)
}
sha1_
=
obj_represent_as_commit
(
gb
,
sha1
,
obj_type
)
noncommit_seen
[
sha1
]
=
sha1_
}
...
...
git-backup_test.go
View file @
cbfa78d2
...
...
@@ -60,6 +60,15 @@ func XSha1(s string) Sha1 {
return
sha1
}
func
xgittype
(
s
string
)
git
.
ObjectType
{
type_
,
ok
:=
gittype
(
s
)
if
!
ok
{
exc
.
Raisef
(
"unknown git type %q"
,
s
)
}
return
type_
}
// verify end-to-end pull-restore
func
TestPullRestore
(
t
*
testing
.
T
)
{
// if something raises -> don't let testing panic - report it as proper error with context.
...
...
@@ -145,7 +154,7 @@ func TestPullRestore(t *testing.T) {
// encoding original object should give sha1_
obj_type
:=
xgit
(
"cat-file"
,
"-t"
,
nc
.
sha1
)
sha1_
:=
obj_represent_as_commit
(
gb
,
nc
.
sha1
,
obj_type
)
sha1_
:=
obj_represent_as_commit
(
gb
,
nc
.
sha1
,
xgittype
(
obj_type
)
)
if
sha1_
!=
nc
.
sha1_
{
t
.
Fatalf
(
"encode %s -> %s ; want %s"
,
sha1
,
sha1_
,
nc
.
sha1_
)
}
...
...
gitobjects.go
View file @
cbfa78d2
...
...
@@ -91,9 +91,8 @@ func (e *UnexpectedObjType) Error() string {
}
type
Tag
struct
{
tagged_type
string
tagged_type
git
.
ObjectType
tagged_sha1
Sha1
// TODO msg
}
...
...
@@ -127,10 +126,16 @@ func (e *TagLoadError) Error() string {
func
tag_parse
(
tag_raw
string
)
(
*
Tag
,
error
)
{
t
:=
Tag
{}
_
,
err
:=
fmt
.
Sscanf
(
tag_raw
,
"object %s
\n
type %s
\n
"
,
&
t
.
tagged_sha1
,
&
t
.
tagged_type
)
tagged_type
:=
""
_
,
err
:=
fmt
.
Sscanf
(
tag_raw
,
"object %s
\n
type %s
\n
"
,
&
t
.
tagged_sha1
,
&
tagged_type
)
if
err
!=
nil
{
return
nil
,
errors
.
New
(
"invalid header"
)
}
var
ok
bool
t
.
tagged_type
,
ok
=
gittype
(
tagged_type
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"invalid tagged type %q"
,
tagged_type
)
}
return
&
t
,
nil
}
...
...
@@ -244,3 +249,37 @@ func xcommit_tree2(g *git.Repository, tree Sha1, parents []Sha1, msg string, aut
func
xcommit_tree
(
g
*
git
.
Repository
,
tree
Sha1
,
parents
[]
Sha1
,
msg
string
)
Sha1
{
return
xcommit_tree2
(
g
,
tree
,
parents
,
msg
,
AuthorInfo
{},
AuthorInfo
{})
}
// gittype converts string to git.ObjectType.
//
// Only valid concrete git types are converted successfully.
func
gittype
(
typ
string
)
(
git
.
ObjectType
,
bool
)
{
switch
typ
{
case
"commit"
:
return
git
.
ObjectCommit
,
true
case
"tree"
:
return
git
.
ObjectTree
,
true
case
"blob"
:
return
git
.
ObjectBlob
,
true
case
"tag"
:
return
git
.
ObjectTag
,
true
}
return
git
.
ObjectBad
,
false
}
// gittypestr converts git.ObjectType to string.
//
// We depend on this conversion being exact and matching how Git encodes it in
// objects. git.ObjectType.String() is different (e.g. "Blob" instead of
// "blob"), and can potentially change over time.
//
// gittypestr expects the type to be valid and concrete - else it panics.
func
gittypestr
(
typ
git
.
ObjectType
)
string
{
switch
typ
{
case
git
.
ObjectCommit
:
return
"commit"
case
git
.
ObjectTree
:
return
"tree"
case
git
.
ObjectBlob
:
return
"blob"
case
git
.
ObjectTag
:
return
"tag"
}
panic
(
fmt
.
Sprintf
(
"git type %#v invalid"
,
typ
))
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment