diff --git a/src/jamidht/conversation.cpp b/src/jamidht/conversation.cpp
index 8a2120b044e7718fb9e56653e6fc9a61a9acf836..83a98283df3e170a11b6a2d9cce2c7102345a6df 100644
--- a/src/jamidht/conversation.cpp
+++ b/src/jamidht/conversation.cpp
@@ -244,8 +244,10 @@ Conversation::Impl::convCommitToMap(const std::vector<ConversationCommit>& commi
                 JAMI_WARN("%s", err.c_str());
             }
         }
+        auto linearizedParent = repository_->linearizedParent(commit.id);
         message["id"] = commit.id;
         message["parents"] = parents;
+        message["linearizedParent"] = linearizedParent ? *linearizedParent : "";
         message["author"] = authorId;
         message["type"] = type;
         message["timestamp"] = std::to_string(commit.timestamp);
diff --git a/src/jamidht/conversationrepository.cpp b/src/jamidht/conversationrepository.cpp
index e86e549d45e335c58ba4e31b71db89dff7c45a41..5607c9a04738cbcf3e07aa8c03dbdd9df9b21dde 100644
--- a/src/jamidht/conversationrepository.cpp
+++ b/src/jamidht/conversationrepository.cpp
@@ -108,6 +108,7 @@ public:
     std::vector<ConversationCommit> log(const std::string& from,
                                         const std::string& to,
                                         unsigned n) const;
+    std::optional<std::string> linearizedParent(const std::string& commitId) const;
 
     GitObject fileAtTree(const std::string& path, const GitTree& tree) const;
     // NOTE! GitDiff needs to be deteleted before repo
@@ -715,7 +716,8 @@ ConversationRepository::Impl::checkVote(const std::string& userDevice,
         return false;
     }
     auto* blob = reinterpret_cast<git_blob*>(vote.get());
-    auto voteContent = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)), git_blob_rawsize(blob));
+    auto voteContent = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)),
+                                        git_blob_rawsize(blob));
     if (!voteContent.empty()) {
         JAMI_ERR("Vote file not empty: %s", votedFile.c_str());
         return false;
@@ -823,7 +825,8 @@ ConversationRepository::Impl::checkValidAdd(const std::string& userDevice,
     }
 
     auto* blob = reinterpret_cast<git_blob*>(blob_invite.get());
-    auto invitation = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)), git_blob_rawsize(blob));
+    auto invitation = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)),
+                                       git_blob_rawsize(blob));
     if (!invitation.empty()) {
         JAMI_ERR("Invitation not empty for commit %s", commitId.c_str());
         return false;
@@ -1100,9 +1103,11 @@ ConversationRepository::Impl::isValidUserAtCommit(const std::string& userDevice,
 
     // Check that certificate matches
     auto* blob = reinterpret_cast<git_blob*>(blob_device.get());
-    auto deviceCert = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)), git_blob_rawsize(blob));
+    auto deviceCert = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)),
+                                       git_blob_rawsize(blob));
     blob = reinterpret_cast<git_blob*>(blob_parent.get());
-    auto parentCert = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)), git_blob_rawsize(blob));
+    auto parentCert = std::string_view(static_cast<const char*>(git_blob_rawcontent(blob)),
+                                       git_blob_rawsize(blob));
     auto deviceCertStr = cert->toString(false);
     auto parentCertStr = cert->issuer->toString(true);
 
@@ -1454,7 +1459,7 @@ ConversationRepository::Impl::log(const std::string& from, const std::string& to
         return commits;
     }
     GitRevWalker walker {walker_ptr, git_revwalk_free};
-    git_revwalk_sorting(walker.get(), GIT_SORT_TOPOLOGICAL);
+    git_revwalk_sorting(walker.get(), GIT_SORT_TOPOLOGICAL | GIT_SORT_TIME);
 
     for (auto idx = 0u; !git_revwalk_next(&oid, walker.get()); ++idx) {
         if (n != 0 && idx == n) {
@@ -1507,6 +1512,45 @@ ConversationRepository::Impl::log(const std::string& from, const std::string& to
     return commits;
 }
 
+std::optional<std::string>
+ConversationRepository::Impl::linearizedParent(const std::string& commitId) const
+{
+    git_oid oid;
+    auto repo = repository();
+    if (!repo or git_reference_name_to_id(&oid, repo.get(), "HEAD") < 0) {
+        JAMI_ERR("Cannot get reference for HEAD");
+        return std::nullopt;
+    }
+
+    git_revwalk* walker_ptr = nullptr;
+    if (git_revwalk_new(&walker_ptr, repo.get()) < 0 || git_revwalk_push(walker_ptr, &oid) < 0) {
+        if (walker_ptr)
+            git_revwalk_free(walker_ptr);
+        // This fail can be ok in the case we check if a commit exists before pulling (so can fail
+        // there). only log if the fail is unwanted.
+        return std::nullopt;
+    }
+    GitRevWalker walker {walker_ptr, git_revwalk_free};
+    git_revwalk_sorting(walker.get(), GIT_SORT_TOPOLOGICAL | GIT_SORT_TIME);
+
+    auto ret = false;
+    for (auto idx = 0u; !git_revwalk_next(&oid, walker.get()); ++idx) {
+        git_commit* commit_ptr = nullptr;
+        std::string id = git_oid_tostr_s(&oid);
+        if (git_commit_lookup(&commit_ptr, repo.get(), &oid) < 0) {
+            JAMI_WARN("Failed to look up commit %s", id.c_str());
+            break;
+        }
+
+        if (ret)
+            return id;
+        if (id == commitId)
+            ret = true;
+    }
+
+    return std::nullopt;
+}
+
 GitObject
 ConversationRepository::Impl::fileAtTree(const std::string& path, const GitTree& tree) const
 {
@@ -2734,6 +2778,12 @@ ConversationRepository::validClone() const
     return pimpl_->validCommits(logN("", 0));
 }
 
+std::optional<std::string>
+ConversationRepository::linearizedParent(const std::string& commitId) const
+{
+    return pimpl_->linearizedParent(commitId);
+}
+
 void
 ConversationRepository::removeBranchWith(const std::string& remoteDevice)
 {
diff --git a/src/jamidht/conversationrepository.h b/src/jamidht/conversationrepository.h
index 71457148a6417e153ccfe77b530ba393c6383b21..2d368db6f11f8e1690f41bd69235b8b6177cbfe3 100644
--- a/src/jamidht/conversationrepository.h
+++ b/src/jamidht/conversationrepository.h
@@ -191,6 +191,12 @@ public:
                                         const std::string& to = "") const;
     std::optional<ConversationCommit> getCommit(const std::string& commitId) const;
 
+    /**
+     * Get parent via topological + date sort in branch main of a commit
+     * @param commitId      id to choice
+     */
+    std::optional<std::string> linearizedParent(const std::string& commitId) const;
+
     /**
      * Merge another branch into the main branch
      * @param merge_id      The reference to merge