Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.1
0.3.2
104 changes: 60 additions & 44 deletions bits/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func (repo *Repository) Install(w io.Writer, conf *Conf) (err error) {
}
} else {
defer f.Close()
_, err = f.WriteString(`#/bin/sh
_, err = f.WriteString(`#!/bin/sh
command -v git-bits >/dev/null 2>&1 || { echo >&2 "This project was setup with git-bits but it can (no longer) be found in your PATH: $PATH."; exit 0; }
git-bits scan | git-bits push
`)
Expand Down Expand Up @@ -624,68 +624,84 @@ func (repo *Repository) Pull(ref string, w io.Writer) (err error) {
for s.Scan() {
err = func() error {
fpath := filepath.Join(repo.rootDir, s.Text())
f, err := os.OpenFile(fpath, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
return err
}
tmpfpath := ""

defer f.Close()
hdr := make([]byte, hex.EncodedLen(KeySize))
_, err = f.Read(hdr)
if err != nil {
//if we cant even read a complete header, its not gonna contain chunks
return nil
}
err = func() error {
f, err := os.OpenFile(fpath, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
return err
}

offs, err := f.Seek(0, 0)
if err != nil || offs != 0 {
return fmt.Errorf("failed to seek files: %v", err)
}
defer f.Close()
hdr := make([]byte, hex.EncodedLen(KeySize))
_, err = f.Read(hdr)
if err != nil {
//if we cant even read a complete header, its not gonna contain chunks
return nil
}

if !bytes.Equal(hdr, repo.header[:len(repo.header)-1]) {
return nil
}
offs, err := f.Seek(0, 0)
if err != nil || offs != 0 {
return fmt.Errorf("failed to seek files: %v", err)
}

//We know its a chunks file that needs filling
tmpf, err := ioutil.TempFile("", "bits_tmp_")
if err != nil {
return err
}
if !bytes.Equal(hdr, repo.header[:len(repo.header)-1]) {
return nil
}

fi, err := f.Stat()
if err != nil {
return fmt.Errorf("failed to stat original file for permissions: %v", err)
}
//We know its a chunks file that needs filling
tmpf, err := ioutil.TempFile("", "bits_tmp_")
if err != nil {
return err
}

//mod the tempfile as the original
err = tmpf.Chmod(fi.Mode())
if err != nil {
return fmt.Errorf("failed to modify temp file permissions: %v", err)
}
tmpfpath = tmpf.Name()
defer tmpf.Close()
fi, err := f.Stat()
if err != nil {
return fmt.Errorf("failed to stat original file for permissions: %v", err)
}

//mod the tempfile as the original
err = os.Chmod(tmpfpath, fi.Mode())
if err != nil {
return fmt.Errorf("failed to modify temp file permissions: %v", err)
}

pr, pw := io.Pipe()
go func() {
defer pw.Close()
err = repo.Fetch(f, pw)
if err != nil {
errCh <- err
}
}()

pr, pw := io.Pipe()
go func() {
defer pw.Close()
err = repo.Fetch(f, pw)
err = repo.Combine(pr, tmpf)
if err != nil {
errCh <- err
return fmt.Errorf("failed to combine: %v", err)
}

return nil
}()

defer tmpf.Close()
err = repo.Combine(pr, tmpf)
if err != nil {
return fmt.Errorf("failed to combine: %v", err)
return err
}

//no tmpfpath means we have no files to move, wer're done here
if tmpfpath == "" {
return nil
}

err = os.Remove(fpath)
if err != nil {
return fmt.Errorf("failed to remove original chunk: %v", err)
return fmt.Errorf("failed to remove original file '%s': %v", fpath, err)
}

err = os.Rename(tmpf.Name(), fpath)
err = os.Rename(tmpfpath, fpath)
if err != nil {
return fmt.Errorf("failed to move '%s' to '%s'", tmpf.Name(), s.Text())
return fmt.Errorf("failed to move '%s' to '%s'", tmpfpath, s.Text())
}

fmt.Fprintf(w3, "%s\n", fpath)
Expand Down
24 changes: 13 additions & 11 deletions bits/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func TestPushFetch(t *testing.T) {
fsize := int64(5 * 1024 * 1024)
fpath := filepath.Join(wd1, fname)
f1 := WriteRandomFile(t, fpath, fsize)
err = f1.Chmod(0755) //add some non-default permission
err = os.Chmod(f1.Name(), 0755)
if err != nil {
t.Error(err)
}
Expand All @@ -309,6 +309,7 @@ func TestPushFetch(t *testing.T) {
}

for i := 0; i < 3; i++ {

func() {
f, err := os.OpenFile(fpath, os.O_RDWR, 0666)
if err != nil {
Expand All @@ -321,17 +322,18 @@ func TestPushFetch(t *testing.T) {
if err != nil {
t.Fatal(err)
}
}()

err = repo1.Git(ctx, nil, nil, "add", "-A")
if err != nil {
t.Fatal(err)
}
err = repo1.Git(ctx, nil, nil, "add", "-A")
if err != nil {
t.Fatal(err)
}

err = repo1.Git(ctx, nil, nil, "commit", "-m", fmt.Sprintf("c%d", i))
if err != nil {
t.Fatal(err)
}

err = repo1.Git(ctx, nil, nil, "commit", "-m", fmt.Sprintf("c%d", i))
if err != nil {
t.Fatal(err)
}
}()
}

orgContent, err := ioutil.ReadFile(filepath.Join(wd1, fname))
Expand Down Expand Up @@ -381,7 +383,7 @@ func TestPushFetch(t *testing.T) {
}

if !bytes.Equal(orgContent, newContent) {
t.Error("after clone and init, file content should be equal to content before edit")
t.Errorf("after clone and init, file content should be equal to content before edit, original has %d bytes new has %d bytes", len(orgContent), len(newContent))
}

buf := bytes.NewBuffer(nil)
Expand Down