summaryrefslogtreecommitdiff
path: root/checkout.go
blob: f4c1d4ef6378e435797fc07da83b084ad26d29f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package git

/*
#include <git2.h>
git_checkout_opts git_checkout_opts_init() {
	git_checkout_opts ret = GIT_CHECKOUT_OPTS_INIT;
	return ret;
}
*/
import "C"
import (
	"runtime"
	"os"
)

type CheckoutStrategy uint

const (
	CheckoutNone                      CheckoutStrategy = C.GIT_CHECKOUT_NONE                         // Dry run, no actual updates
	CheckoutSafe                                       = C.GIT_CHECKOUT_SAFE                         // Allow safe updates that cannot overwrite uncommitted data
	CheckoutSafeCreate                                 = C.GIT_CHECKOUT_SAFE_CREATE                  // Allow safe updates plus creation of missing files
	CheckoutForce                                      = C.GIT_CHECKOUT_FORCE                        // Allow all updates to force working directory to look like index
	CheckoutAllowConflicts                             = C.GIT_CHECKOUT_ALLOW_CONFLICTS              // Allow checkout to make safe updates even if conflicts are found
	CheckoutRemoveUntracked                            = C.GIT_CHECKOUT_REMOVE_UNTRACKED             // Remove untracked files not in index (that are not ignored)
	CheckoutRemoveIgnored                              = C.GIT_CHECKOUT_REMOVE_IGNORED               // Remove ignored files not in index
	CheckotUpdateOnly                                  = C.GIT_CHECKOUT_UPDATE_ONLY                  // Only update existing files, don't create new ones
	CheckoutDontUpdateIndex                            = C.GIT_CHECKOUT_DONT_UPDATE_INDEX            // Normally checkout updates index entries as it goes; this stops that
	CheckoutNoRefresh                                  = C.GIT_CHECKOUT_NO_REFRESH                   // Don't refresh index/config/etc before doing checkout
	CheckooutDisablePathspecMatch                      = C.GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH       // Treat pathspec as simple list of exact match file paths
	CheckoutSkipUnmerged                               = C.GIT_CHECKOUT_SKIP_UNMERGED                // Allow checkout to skip unmerged files (NOT IMPLEMENTED)
	CheckoutUserOurs                                   = C.GIT_CHECKOUT_USE_OURS                     // For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED)
	CheckoutUseTheirs                                  = C.GIT_CHECKOUT_USE_THEIRS                   // For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED)
	CheckoutUpdateSubmodules                           = C.GIT_CHECKOUT_UPDATE_SUBMODULES            // Recursively checkout submodules with same options (NOT IMPLEMENTED)
	CheckoutUpdateSubmodulesIfChanged                  = C.GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED // Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED)
)

type CheckoutOpts struct {
	Strategy       CheckoutStrategy // Default will be a dry run
	DisableFilters bool				// Don't apply filters like CRLF conversion
	DirMode        os.FileMode		// Default is 0755
	FileMode       os.FileMode		// Default is 0644 or 0755 as dictated by blob
	FileOpenFlags  int				// Default is O_CREAT | O_TRUNC | O_WRONLY
}

// Convert the CheckoutOpts struct to the corresponding C-struct
func populateCheckoutOpts(ptr *C.git_checkout_opts, opts *CheckoutOpts) {
	*ptr = C.git_checkout_opts_init()
	if opts == nil {
		return
	}
	ptr.checkout_strategy = C.uint(opts.Strategy)
	ptr.disable_filters = cbool(opts.DisableFilters)
	ptr.dir_mode = C.uint(opts.DirMode.Perm())
	ptr.file_mode = C.uint(opts.FileMode.Perm())
}

// Updates files in the index and the working tree to match the content of
// the commit pointed at by HEAD.
func (v *Repository) Checkout(opts *CheckoutOpts) error {
	var copts C.git_checkout_opts
	populateCheckoutOpts(&copts, opts)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_checkout_head(v.ptr, &copts)
	if ret < 0 {
		return LastError()
	}

	return nil
}

// Updates files in the working tree to match the content of the index.
func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error {
	var copts C.git_checkout_opts
	populateCheckoutOpts(&copts, opts)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_checkout_index(v.ptr, index.ptr, &copts)
	if ret < 0 {
		return LastError()
	}

	return nil
}