Repository: ericsson/codechecker
Issue: Diffing two runs in the command line on the server results in "source file contents changed" error

**Describe the bug**
When diffing two runs from a command-line client, a _"The following source file contents changed since the latest analysis:"_ error is shown instead of the diff.

**CodeChecker version**
Just built the latest master half an hour ago. Server started on this version, too.
~~~~
CodeChecker web version:
------------------------------------------------------------------------
Kind                          | Version
------------------------------------------------------------------------
Base package version          | 6.16.0
Package build date            | 2021-02-08T10:48
Git commit ID (hash)          | 6626d77afa5807b800ca70e084a2933c110f66b4
Git tag information           | 6.16
Server supported API (Thrift) | 6.39
Client API (Thrift)           | 6.39
------------------------------------------------------------------------
~~~~

**To Reproduce**
This is what I did.

1. Do one analysis, store it with some name, in my case `bitcoin__len2`.
2. Do another analysis, store it with another name, in my case `bitcoin__len2-nobool`.
3. Both analyses were stored with a `--trim-path-prefix` with the root directory of the project (in my case `/home/user/projects/Bitcoin`). Not sure if this counts in any way, however...
4. On a **completely different machine** (:warning: i.e. **the source files are NOT available locally** for either of the analyses! :warning:) execute: `CodeChecker cmd diff --url http://localhost:16670/AdjacentParams -b bitcoin__len2 -n bitcoin__len2-nobool --resolved`
5. Observe error:

~~~~
----==== Summary ====----
----=================----
Total number of reports: 58
----=================----

[WARNING 2021-02-08 11:00] - The following source file contents changed since the latest analysis:
 - src/bench/wallet_balance.cpp
 - src/qt/platformstyle.cpp
 - src/net_processing.cpp
 - src/txdb.cpp
 - src/index/base.cpp
 - src/wallet/wallet.cpp
 - src/core_read.cpp
 - src/qt/modaloverlay.cpp
 - src/dbwrapper.cpp
 - src/qt/optionsmodel.cpp
 - src/test/descriptor_tests.cpp
 - src/node/transaction.cpp
 - src/index/txindex.cpp
 - src/validation.cpp
 - src/qt/walletmodel.cpp
 - src/qt/bitcoin.cpp
 - src/net.cpp
 - src/rpc/util.cpp
 - src/wallet/psbtwallet.cpp
 - src/index/blockfilterindex.cpp
Multiple reports were not shown and skipped from the statistics. Please analyze your project again to update the reports!
[INFO 2021-02-08 11:00] - Compared multiple remote runs bitcoin__len2 (matching: bitcoin__len2) and bitcoin__len2-nobool (matching: bitcoin__len2-nobool)
~~~~

**Expected behaviour**
The difference, from the server as-is, shown in the client. It works when you do the same thing in the web app.

**Additional context**
Some output options (detailed below) still work:

 * `-o plaintext`: :negative_squared_cross_mark:
 * `-o rows`: :negative_squared_cross_mark:
 * `-o table`: :negative_squared_cross_mark:
 * `-o csv`: :negative_squared_cross_mark:
 * `-o json`: :heavy_check_mark: 
 * `-o html -e random_result_dir`: :heavy_check_mark:
 * `-o gerrit`: :heavy_check_mark: 
 * `-o codeclimate`: :heavy_check_mark: 


Changed files:
web/tests/functional/diff_remote/__init__.py, web/client/codechecker_client/cmd_line_client.py

diff --git a/web/client/codechecker_client/cmd_line_client.py b/web/client/codechecker_client/cmd_line_client.py
index 3ad4ccb9..84c8b91a 100644
--- a/web/client/codechecker_client/cmd_line_client.py
+++ b/web/client/codechecker_client/cmd_line_client.py
@@ -1208,16 +1208,24 @@ def handle_diff_results(args):
         # Convert all the reports to the common Report
         # type for printing and formatting to various formats.
         converted_reports = []
+        changed_files = set()
         for report in reports:
             if not isinstance(report, Report):
                 r = report_type_converter.reportData_to_report(report)
                 if source_line_contents:
-                    source_line = convert.from_b64(
+                    r.source_line = convert.from_b64(
                         source_line_contents[report.fileId][report.line])
-                    r.source_line = source_line
                 converted_reports.append(r)
             else:
+                if not os.path.exists(report.file_path):
+                    changed_files.add(report.file_path)
+                    continue
+
+                report.source_line = util.get_line(report.file_path,
+                                                   report.line)
+
                 converted_reports.append(report)
+
         reports = converted_reports
 
         repo_dir = os.environ.get('CC_REPO_DIR')
@@ -1265,20 +1273,16 @@ def handle_diff_results(args):
         file_stats = defaultdict(int)
         severity_stats = defaultdict(int)
 
-        changed_files = set()
         for report in reports:
+            if report.source_line is None:
+                continue
+
             severity = context.severity_map.get(report.check_name,
                                                 'UNSPECIFIED')
             file_name = report.file_path
             checked_file = file_name \\
                 + ':' + str(report.line) + ":" + str(report.col)
             check_msg = report.description
-            source_line = None
-            if os.path.exists(file_name):
-                source_line = util.get_line(file_name, report.line)
-            if source_line is None:
-                changed_files.add(file_name)
-                continue
 
             rows.append((severity,
                          checked_file,
diff --git a/web/tests/functional/diff_remote/__init__.py b/web/tests/functional/diff_remote/__init__.py
index 561058c5..b185d8ab 100644
--- a/web/tests/functional/diff_remote/__init__.py
+++ b/web/tests/functional/diff_remote/__init__.py
@@ -189,6 +189,10 @@ def setup_package():
     # Export the test configuration to the workspace.
     env.export_test_cfg(TEST_WORKSPACE, test_config)
 
+    # Remove report directories which are not used anymore.
+    shutil.rmtree(test_proj_path_base)
+    shutil.rmtree(test_proj_path_new)
+
 
 def teardown_package():
     """Clean up after the test."""