@@ -13,9 +13,28 @@ import (
1313 "github.com/spf13/cobra"
1414)
1515
16+ var (
17+ checkoutTo string
18+ checkoutBase bool
19+ checkoutOurs bool
20+ checkoutTheirs bool
21+ )
22+
1623func checkoutCommand (cmd * cobra.Command , args []string ) {
1724 requireInRepo ()
1825
26+ stage , err := whichCheckout ()
27+ if err != nil {
28+ Exit ("Error parsing args: %v" , err )
29+ }
30+
31+ if checkoutTo != "" && stage != git .IndexStageDefault {
32+ checkoutConflict (rootedPaths (args )[0 ], stage )
33+ return
34+ } else if checkoutTo != "" || stage != git .IndexStageDefault {
35+ Exit ("--to and exactly one of --theirs, --ours, and --base must be used together" )
36+ }
37+
1938 msg := []string {
2039 "WARNING: 'git lfs checkout' is deprecated and will be removed in v3.0.0." ,
2140
@@ -75,6 +94,63 @@ func checkoutCommand(cmd *cobra.Command, args []string) {
7594 singleCheckout .Close ()
7695}
7796
97+ func checkoutConflict (file string , stage git.IndexStage ) {
98+ singleCheckout := newSingleCheckout (cfg .Git , "" )
99+ if singleCheckout .Skip () {
100+ fmt .Println ("Cannot checkout LFS objects, Git LFS is not installed." )
101+ return
102+ }
103+
104+ ref , err := git .ResolveRef (fmt .Sprintf (":%d:%s" , stage , file ))
105+ if err != nil {
106+ Exit ("Could not checkout (are you not in the middle of a merge?): %v" , err )
107+ }
108+
109+ scanner , err := git .NewObjectScanner ()
110+ if err != nil {
111+ Exit ("Could not create object scanner: %v" , err )
112+ }
113+
114+ if ! scanner .Scan (ref .Sha ) {
115+ Exit ("Could not find object %q" , ref .Sha )
116+ }
117+
118+ ptr , err := lfs .DecodePointer (scanner .Contents ())
119+ if err != nil {
120+ Exit ("Could not find decoder pointer for object %q: %v" , ref .Sha , err )
121+ }
122+
123+ p := & lfs.WrappedPointer {Name : file , Pointer : ptr }
124+
125+ if err := singleCheckout .RunToPath (p , checkoutTo ); err != nil {
126+ Exit ("Error checking out %v to %q: %v" , ref .Sha , checkoutTo , err )
127+ }
128+ singleCheckout .Close ()
129+ }
130+
131+ func whichCheckout () (stage git.IndexStage , err error ) {
132+ seen := 0
133+ stage = git .IndexStageDefault
134+
135+ if checkoutBase {
136+ seen ++
137+ stage = git .IndexStageBase
138+ }
139+ if checkoutOurs {
140+ seen ++
141+ stage = git .IndexStageOurs
142+ }
143+ if checkoutTheirs {
144+ seen ++
145+ stage = git .IndexStageTheirs
146+ }
147+
148+ if seen > 1 {
149+ return 0 , fmt .Errorf ("At most one of --base, --theirs, and --ours is allowed" )
150+ }
151+ return stage , nil
152+ }
153+
78154// Parameters are filters
79155// firstly convert any pathspecs to the root of the repo, in case this is being
80156// executed in a sub-folder
@@ -92,5 +168,10 @@ func rootedPaths(args []string) []string {
92168}
93169
94170func init () {
95- RegisterCommand ("checkout" , checkoutCommand , nil )
171+ RegisterCommand ("checkout" , checkoutCommand , func (cmd * cobra.Command ) {
172+ cmd .Flags ().StringVar (& checkoutTo , "to" , "" , "Checkout a conflicted file to this path" )
173+ cmd .Flags ().BoolVar (& checkoutOurs , "ours" , false , "Checkout our version of a conflicted file" )
174+ cmd .Flags ().BoolVar (& checkoutTheirs , "theirs" , false , "Checkout their version of a conflicted file" )
175+ cmd .Flags ().BoolVar (& checkoutBase , "base" , false , "Checkout the base version of a conflicted file" )
176+ })
96177}
0 commit comments