@@ -62,7 +62,7 @@ var flSubmodules = flag.String("submodules", envString("GIT_SYNC_SUBMODULES", "r
6262var flRoot = flag .String ("root" , envString ("GIT_SYNC_ROOT" , envString ("HOME" , "" )+ "/git" ),
6363 "the root directory for git-sync operations, under which --dest will be created" )
6464var flDest = flag .String ("dest" , envString ("GIT_SYNC_DEST" , "" ),
65- "the name of (a symlink to) a directory in which to check-out files under --root (defaults to the leaf dir of --repo)" )
65+ "the path (absolute or relative to --root) at which to create a symlink to the directory holding the checked-out files (defaults to the leaf dir of --repo)" )
6666var flErrorFile = flag .String ("error-file" , envString ("GIT_SYNC_ERROR_FILE" , "" ),
6767 "the name of a file into which errors will be written under --root (defaults to \" \" , disabling error reporting)" )
6868var flWait = flag .Float64 ("wait" , envFloat ("GIT_SYNC_WAIT" , 1 ),
@@ -286,9 +286,8 @@ func main() {
286286 parts := strings .Split (strings .Trim (* flRepo , "/" ), "/" )
287287 * flDest = parts [len (parts )- 1 ]
288288 }
289-
290- if strings .Contains (* flDest , "/" ) {
291- handleError (true , "ERROR: --dest must be a leaf name, not a path" )
289+ if ! filepath .IsAbs (* flDest ) {
290+ * flDest = filepath .Join (* flRoot , * flDest )
292291 }
293292
294293 if * flWait < 0 {
@@ -646,28 +645,36 @@ func addUser() error {
646645// directory and cleans up the previous worktree. If there was a previous
647646// worktree, this returns the path to it.
648647func updateSymlink (ctx context.Context , gitRoot , link , newDir string ) (string , error ) {
648+ linkDir , linkFile := filepath .Split (link )
649+
650+ // Make sure the link directory exists. We do this here, rather than at
651+ // startup because it might be under --root and that gets wiped in some
652+ // circumstances.
653+ if err := os .MkdirAll (filepath .Dir (linkDir ), os .FileMode (int (0755 ))); err != nil {
654+ return "" , fmt .Errorf ("error making symlink dir: %v" , err )
655+ }
656+
649657 // Get currently-linked repo directory (to be removed), unless it doesn't exist
650- linkPath := filepath .Join (gitRoot , link )
651- oldWorktreePath , err := filepath .EvalSymlinks (linkPath )
658+ oldWorktreePath , err := filepath .EvalSymlinks (link )
652659 if err != nil && ! os .IsNotExist (err ) {
653660 return "" , fmt .Errorf ("error accessing current worktree: %v" , err )
654661 }
655662
656663 // newDir is absolute, so we need to change it to a relative path. This is
657664 // so it can be volume-mounted at another path and the symlink still works.
658- newDirRelative , err := filepath .Rel (gitRoot , newDir )
665+ newDirRelative , err := filepath .Rel (linkDir , newDir )
659666 if err != nil {
660667 return "" , fmt .Errorf ("error converting to relative path: %v" , err )
661668 }
662669
663670 const tmplink = "tmp-link"
664- log .V (1 ).Info ("creating tmp symlink" , "root" , gitRoot , "dst" , newDirRelative , "src" , tmplink )
665- if _ , err := cmdRunner .Run (ctx , gitRoot , "ln" , "-snf" , newDirRelative , tmplink ); err != nil {
671+ log .V (1 ).Info ("creating tmp symlink" , "root" , linkDir , "dst" , newDirRelative , "src" , tmplink )
672+ if _ , err := cmdRunner .Run (ctx , linkDir , "ln" , "-snf" , newDirRelative , tmplink ); err != nil {
666673 return "" , fmt .Errorf ("error creating symlink: %v" , err )
667674 }
668675
669- log .V (1 ).Info ("renaming symlink" , "root" , gitRoot , "old_name" , tmplink , "new_name" , link )
670- if _ , err := cmdRunner .Run (ctx , gitRoot , "mv" , "-T" , tmplink , link ); err != nil {
676+ log .V (1 ).Info ("renaming symlink" , "root" , linkDir , "old_name" , tmplink , "new_name" , linkFile )
677+ if _ , err := cmdRunner .Run (ctx , linkDir , "mv" , "-T" , tmplink , linkFile ); err != nil {
671678 return "" , fmt .Errorf ("error replacing symlink: %v" , err )
672679 }
673680
@@ -980,8 +987,7 @@ func syncRepo(ctx context.Context, repo, branch, rev string, depth int, gitRoot,
980987 askpassCount .WithLabelValues (metricKeySuccess ).Inc ()
981988 }
982989
983- target := filepath .Join (gitRoot , dest )
984- gitRepoPath := filepath .Join (target , ".git" )
990+ gitRepoPath := filepath .Join (gitRoot , ".git" )
985991 var hash string
986992 _ , err := os .Stat (gitRepoPath )
987993 switch {
@@ -999,7 +1005,7 @@ func syncRepo(ctx context.Context, repo, branch, rev string, depth int, gitRoot,
9991005 return false , "" , fmt .Errorf ("error checking if repo exists %q: %v" , gitRepoPath , err )
10001006 default :
10011007 // Not the first time. Figure out if the ref has changed.
1002- local , remote , err := getRevs (ctx , target , branch , rev )
1008+ local , remote , err := getRevs (ctx , dest , branch , rev )
10031009 if err != nil {
10041010 return false , "" , err
10051011 }
0 commit comments