@@ -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 {
@@ -627,28 +626,36 @@ func addUser() error {
627626// directory and cleans up the previous worktree. If there was a previous
628627// worktree, this returns the path to it.
629628func updateSymlink (ctx context.Context , gitRoot , link , newDir string ) (string , error ) {
629+ linkDir , linkFile := filepath .Split (link )
630+
631+ // Make sure the link directory exists. We do this here, rather than at
632+ // startup because it might be under --root and that gets wiped in some
633+ // circumstances.
634+ if err := os .MkdirAll (filepath .Dir (linkDir ), os .FileMode (int (0755 ))); err != nil {
635+ return "" , fmt .Errorf ("error making symlink dir: %v" , err )
636+ }
637+
630638 // Get currently-linked repo directory (to be removed), unless it doesn't exist
631- linkPath := filepath .Join (gitRoot , link )
632- oldWorktreePath , err := filepath .EvalSymlinks (linkPath )
639+ oldWorktreePath , err := filepath .EvalSymlinks (link )
633640 if err != nil && ! os .IsNotExist (err ) {
634641 return "" , fmt .Errorf ("error accessing current worktree: %v" , err )
635642 }
636643
637644 // newDir is absolute, so we need to change it to a relative path. This is
638645 // so it can be volume-mounted at another path and the symlink still works.
639- newDirRelative , err := filepath .Rel (gitRoot , newDir )
646+ newDirRelative , err := filepath .Rel (linkDir , newDir )
640647 if err != nil {
641648 return "" , fmt .Errorf ("error converting to relative path: %v" , err )
642649 }
643650
644651 const tmplink = "tmp-link"
645- log .V (1 ).Info ("creating tmp symlink" , "root" , gitRoot , "dst" , newDirRelative , "src" , tmplink )
646- if _ , err := cmdRunner .Run (ctx , gitRoot , "ln" , "-snf" , newDirRelative , tmplink ); err != nil {
652+ log .V (1 ).Info ("creating tmp symlink" , "root" , linkDir , "dst" , newDirRelative , "src" , tmplink )
653+ if _ , err := cmdRunner .Run (ctx , linkDir , "ln" , "-snf" , newDirRelative , tmplink ); err != nil {
647654 return "" , fmt .Errorf ("error creating symlink: %v" , err )
648655 }
649656
650- log .V (1 ).Info ("renaming symlink" , "root" , gitRoot , "old_name" , tmplink , "new_name" , link )
651- if _ , err := cmdRunner .Run (ctx , gitRoot , "mv" , "-T" , tmplink , link ); err != nil {
657+ log .V (1 ).Info ("renaming symlink" , "root" , linkDir , "old_name" , tmplink , "new_name" , linkFile )
658+ if _ , err := cmdRunner .Run (ctx , linkDir , "mv" , "-T" , tmplink , linkFile ); err != nil {
652659 return "" , fmt .Errorf ("error replacing symlink: %v" , err )
653660 }
654661
@@ -958,8 +965,7 @@ func syncRepo(ctx context.Context, repo, branch, rev string, depth int, gitRoot,
958965 askpassCount .WithLabelValues (metricKeySuccess ).Inc ()
959966 }
960967
961- target := filepath .Join (gitRoot , dest )
962- gitRepoPath := filepath .Join (target , ".git" )
968+ gitRepoPath := filepath .Join (gitRoot , ".git" )
963969 var hash string
964970 _ , err := os .Stat (gitRepoPath )
965971 switch {
@@ -977,7 +983,7 @@ func syncRepo(ctx context.Context, repo, branch, rev string, depth int, gitRoot,
977983 return false , "" , fmt .Errorf ("error checking if repo exists %q: %v" , gitRepoPath , err )
978984 default :
979985 // Not the first time. Figure out if the ref has changed.
980- local , remote , err := getRevs (ctx , target , branch , rev )
986+ local , remote , err := getRevs (ctx , dest , branch , rev )
981987 if err != nil {
982988 return false , "" , err
983989 }
0 commit comments