diff --git a/cvsps.c b/cvsps.c
index 81c6e21..9135641 100644
--- a/cvsps.c
+++ b/cvsps.c
@@ -149,6 +149,8 @@ static int before_tag(CvsFileRevision * rev, const char * tag);
 static void determine_branch_ancestor(PatchSet * ps, PatchSet * head_ps);
 static void handle_collisions();
 
+static void move_branchpoints();
+
 int main(int argc, char *argv[])
 {
     debuglvl = DEBUG_APPERROR|DEBUG_SYSERROR|DEBUG_APPMSG1;
@@ -224,6 +226,8 @@ int main(int argc, char *argv[])
     ps_counter = 0;
     walk_all_patch_sets(assign_patchset_id);
 
+    move_branchpoints();
+
     handle_collisions();
 
     resolve_global_symbols();
@@ -2689,3 +2693,73 @@ void walk_all_patch_sets(void (*action)(PatchSet *))
 	action(ps);
     }
 }
+
+/* Given a revision number like A.B.C, remove the last part leaving just
+ * A.B.
+ */
+static char *strip_last_part(const char *revstr)
+{
+    char *s;
+    
+    s = strdup(revstr);
+    *strrchr(s, '.') = '\0';
+    return s;
+}
+
+/* For each branch, find the branchpoint, and move the first commit on the
+ * branch right after the branch point.
+ */
+static void move_branchpoints(void)
+{
+    struct hash_entry * he;
+
+    reset_hash_iterator(branch_heads);
+    while ((he = next_hash_entry(branch_heads)))
+    {
+        char *branch = he->he_key;
+	PatchSet *head_ps = (PatchSet*)he->he_obj;
+	struct hash_entry * filehe;
+	int branchpoint = -1;
+
+	/* loop all files on the branch, and find the last patchset on the
+	 * ancestor branch that introduces a revision needed for the branch
+	 */
+	reset_hash_iterator(file_hash);
+	while ((filehe = next_hash_entry(file_hash)))
+        {
+            CvsFile *file = (CvsFile *) filehe->he_obj;
+            char *revstr = (char *)get_hash_object(file->branches_sym, branch);
+	    CvsFileRevision *rev;
+
+	    if (revstr == NULL)
+                continue;
+
+	    revstr = strip_last_part(revstr);
+
+	    rev = (CvsFileRevision *)get_hash_object(file->revisions, revstr);
+	    debug(DEBUG_STATUS, "branch %s file %s rev %s ps %d",
+		  branch, rev->file->filename, revstr,
+		  rev->post_psm->ps->psid);
+	    /* If it's a new file in this branch, ignore it */
+	    if (rev->post_psm->pre_rev != NULL &&
+		(branchpoint == -1 || rev->post_psm->ps->psid > branchpoint))
+                branchpoint = rev->post_psm->ps->psid;
+	    free(revstr);
+        }
+	debug(DEBUG_STATUS, "branch %s branchpoint %d", branch, branchpoint);
+
+	/*
+	 * Move the first patchset in the new branch right after the
+	 * branchpoint.
+	 */
+	while(head_ps->psid > branchpoint + 1)
+        {
+            PatchSet *prev = list_entry(head_ps->all_link.prev, PatchSet, all_link);
+	    list_del(&head_ps->all_link);
+	    list_add(&head_ps->all_link, prev->all_link.prev);
+
+	    head_ps->psid--;
+	    prev->psid++;
+        }
+    }
+}
