d068d2fb67acf09e2b8b333a32c099da418a8df9
angie
  Tue Sep 10 14:12:30 2019 -0700
When re-saving a session, if userdata ctfile already exists, just recreate it instead of errAborting; otherwise, the session can never be saved after an initial timeout or other problem.  refs #24121.

diff --git src/hg/hgSession/sessionData.c src/hg/hgSession/sessionData.c
index b14caaa..bdccdf4 100644
--- src/hg/hgSession/sessionData.c
+++ src/hg/hgSession/sessionData.c
@@ -90,31 +90,36 @@
         if (existingLink[0] != '/')
             {
             char trashPathDir[PATH_LEN];
             splitPath(trashPath, trashPathDir, NULL, NULL);
             char fullLinkPath[strlen(trashPathDir) + strlen(existingLink) + 1];
             safef(fullLinkPath, sizeof fullLinkPath, "%s%s", trashPathDir, existingLink);
             newPath = realpath(fullLinkPath, NULL);
             }
         else
             newPath = existingLink;
         }
     else
         {
         newPath = sessionDataPathFromTrash(trashPath, sessionDir);
         if (fileExists(newPath))
-            errAbort("saveTrashFile: new path '%s' already exists", newPath);
+            {
+            if (unlink(newPath) != 0)
+                errnoAbort("saveTrashFile: newPath='%s' already existed but unlink failed",
+                           newPath);
+            fprintf(stderr, "saveTrashFile: new path '%s' already exists; overwriting", newPath);
+            }
         makeDirsForFile(newPath);
         moveAndLink(trashPath, newPath);
         }
     }
 return newPath;
 }
 
 static char *nextTrashPath(char *string, char *trashDirPrefix)
 /* Alloc & return the next file path in string that starts with "../trash/", or NULL. */
 {
 char *trashPath = NULL;
 if (isNotEmpty(string))
     {
     char *pathStart = stringIn(trashDirPrefix, string);
     if (pathStart)
@@ -366,31 +371,31 @@
 /* oldFile contains custom track lines or track collection hub trackDb; scan for trashDir paths
  * and/or customTrash tables and move files and tables to safe locations per sessionDataDbPrefix and
  * sessionDir.  If oldFile does not exist or has already been saved, return NULL. */
 {
 char *newFile = NULL;
 if (fileExists(oldFile))
     {
     if (isTrashPath(oldFile))
         {
         struct lineFile *lf = lineFileOpen(oldFile, TRUE);
         if (isNotEmpty(sessionDir))
             newFile = sessionDataPathFromTrash(oldFile, sessionDir);
         else
             newFile = newCtTrashFile();
         if (fileExists(newFile))
-            errAbort("saveTrackFile: new file '%s' already exists", newFile);
+            fprintf(stderr, "saveTrackFile: new file '%s' already exists", newFile);
         makeDirsForFile(newFile);
         FILE *newF = mustOpen(newFile, "w");
         char *line;
         while (lineFileNext(lf, &line, NULL))
             {
             char *s = skipLeadingSpaces(line);
             if (*s != '\0' && *s != '#')
                 {
                 char *trackLine = cloneString(line);
                 saveTrashPaths(&trackLine, sessionDir, FALSE);
                 saveDbTableName(&trackLine, sessionDataDbPrefix, dbSuffix, sessionDir);
                 fprintf(newF, "%s\n", trackLine);
                 freeMem(trackLine);
                 }
             else