@@ -18,10 +18,34 @@ import (
1818)
1919
2020const (
21- MetadataPath = ".git/cross/metadata.json"
22- CrossfilePath = "Crossfile"
21+ MetadataRelPath = ".git/cross/metadata.json"
22+ CrossfileRelPath = "Crossfile"
2323)
2424
25+ func getRepoRoot () (string , error ) {
26+ out , err := exec .Command ("git" , "rev-parse" , "--show-toplevel" ).Output ()
27+ if err != nil {
28+ return "" , err
29+ }
30+ return strings .TrimSpace (string (out )), nil
31+ }
32+
33+ func getMetadataPath () (string , error ) {
34+ root , err := getRepoRoot ()
35+ if err != nil {
36+ return "" , err
37+ }
38+ return filepath .Join (root , MetadataRelPath ), nil
39+ }
40+
41+ func getCrossfilePath () (string , error ) {
42+ root , err := getRepoRoot ()
43+ if err != nil {
44+ return "" , err
45+ }
46+ return filepath .Join (root , CrossfileRelPath ), nil
47+ }
48+
2549type Patch struct {
2650 Remote string `json:"remote"`
2751 RemotePath string `json:"remote_path"`
@@ -110,7 +134,11 @@ func logError(msg string) {
110134
111135func loadMetadata () (Metadata , error ) {
112136 var meta Metadata
113- data , err := os .ReadFile (MetadataPath )
137+ path , err := getMetadataPath ()
138+ if err != nil {
139+ return meta , err
140+ }
141+ data , err := os .ReadFile (path )
114142 if err != nil {
115143 if os .IsNotExist (err ) {
116144 return meta , nil
@@ -122,20 +150,28 @@ func loadMetadata() (Metadata, error) {
122150}
123151
124152func saveMetadata (meta Metadata ) error {
125- dir := filepath .Dir (MetadataPath )
153+ path , err := getMetadataPath ()
154+ if err != nil {
155+ return err
156+ }
157+ dir := filepath .Dir (path )
126158 if err := os .MkdirAll (dir , 0o755 ); err != nil {
127159 return err
128160 }
129161 data , err := json .MarshalIndent (meta , "" , " " )
130162 if err != nil {
131163 return err
132164 }
133- return os .WriteFile (MetadataPath , data , 0o644 )
165+ return os .WriteFile (path , data , 0o644 )
134166}
135167
136168func updateCrossfile (line string ) error {
169+ path , err := getCrossfilePath ()
170+ if err != nil {
171+ return err
172+ }
137173 line = strings .TrimSpace (line )
138- data , err := os .ReadFile (CrossfilePath )
174+ data , err := os .ReadFile (path )
139175 if err != nil && ! os .IsNotExist (err ) {
140176 return err
141177 }
@@ -145,7 +181,7 @@ func updateCrossfile(line string) error {
145181 return nil
146182 }
147183
148- f , err := os .OpenFile (CrossfilePath , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0o644 )
184+ f , err := os .OpenFile (path , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0o644 )
149185 if err != nil {
150186 return err
151187 }
@@ -212,8 +248,57 @@ func detectDefaultBranch(url string) (string, error) {
212248 return "main" , nil
213249}
214250
251+ func repoRelativePath () (string , error ) {
252+ out , err := git .NewCommand ("rev-parse" , "--show-toplevel" ).RunInDir ("." )
253+ if err != nil {
254+ return "" , err
255+ }
256+ root := strings .TrimSpace (string (out ))
257+ cwd , err := os .Getwd ()
258+ if err != nil {
259+ return "" , err
260+ }
261+ rel , err := filepath .Rel (root , cwd )
262+ if err != nil {
263+ return "" , err
264+ }
265+ rel = filepath .ToSlash (rel )
266+ if rel == "." {
267+ return "" , nil
268+ }
269+ return strings .Trim (rel , "/" ), nil
270+ }
271+
272+ func findPatchForPath (meta Metadata , rel string ) * Patch {
273+ rel = strings .Trim (strings .TrimSpace (rel ), "/" )
274+ if rel == "" {
275+ return nil
276+ }
277+
278+ var selected * Patch
279+ longest := - 1
280+ for i := range meta .Patches {
281+ lp := strings .Trim (meta .Patches [i ].LocalPath , "/" )
282+ if lp == "" {
283+ continue
284+ }
285+ if rel == lp || strings .HasPrefix (rel , lp + "/" ) {
286+ if len (lp ) > longest {
287+ longest = len (lp )
288+ selected = & meta .Patches [i ]
289+ }
290+ }
291+ }
292+
293+ return selected
294+ }
295+
296+ // selectPatchWithFZF is removed as it was only used by wt command.
297+
215298func main () {
299+ var dry string
216300 rootCmd := & cobra.Command {Use : "git-cross" }
301+ rootCmd .PersistentFlags ().StringVar (& dry , "dry" , "" , "Dry run command (e.g. echo)" )
217302
218303 useCmd := & cobra.Command {
219304 Use : "use [name] [url]" ,
@@ -505,12 +590,16 @@ func main() {
505590 Short : "Re-execute all Crossfile commands" ,
506591 RunE : func (cmd * cobra.Command , args []string ) error {
507592 logInfo ("Replaying Crossfile..." )
508- _ , err := os .ReadFile (CrossfilePath )
593+ path , err := getCrossfilePath ()
594+ if err != nil {
595+ return err
596+ }
597+ _ , err = os .ReadFile (path )
509598 if err != nil {
510599 return err
511600 }
512601 currExe , _ := os .Executable ()
513- script := fmt .Sprintf (`cross() { "%s" "$@"; }; source "%s"` , currExe , CrossfilePath )
602+ script := fmt .Sprintf (`cross() { "%s" "$@"; }; source "%s"` , currExe , path )
514603 c := exec .Command ("bash" , "-c" , script )
515604 c .Stdout = os .Stdout
516605 c .Stderr = os .Stderr
@@ -639,11 +728,12 @@ func main() {
639728 Use : "init" ,
640729 Short : "Initialize a new project with Crossfile" ,
641730 RunE : func (cmd * cobra.Command , args []string ) error {
642- if _ , err := os .Stat (CrossfilePath ); err == nil {
731+ path := "Crossfile"
732+ if _ , err := os .Stat (path ); err == nil {
643733 logInfo ("Crossfile already exists." )
644734 return nil
645735 }
646- err := os .WriteFile (CrossfilePath , []byte ("# git-cross configuration\n " ), 0o644 )
736+ err := os .WriteFile (path , []byte ("# git-cross configuration\n " ), 0o644 )
647737 if err != nil {
648738 return err
649739 }
0 commit comments