⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 merge.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * merge.c:  merging changes into a working file
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */



#include "svn_wc.h"
#include "svn_diff.h"
#include "svn_config.h"
#include "svn_path.h"

#include "wc.h"
#include "entries.h"
#include "translate.h"
#include "questions.h"

#include "svn_private_config.h"



svn_error_t *
svn_wc_merge (const char *left,
              const char *right,
              const char *merge_target,
              svn_wc_adm_access_t *adm_access,
              const char *left_label,
              const char *right_label,
              const char *target_label,
              svn_boolean_t dry_run,
              enum svn_wc_merge_outcome_t *merge_outcome,
              const char *diff3_cmd,
              apr_pool_t *pool)
{
  const char *tmp_target, *result_target, *tmp_left, *tmp_right;
  const char *mt_pt, *mt_bn;
  apr_file_t *tmp_f, *result_f;
  svn_boolean_t is_binary;
  svn_subst_keywords_t *keywords;
  const char *eol;
  const svn_wc_entry_t *entry;
  svn_boolean_t contains_conflicts, special;

  svn_path_split (merge_target, &mt_pt, &mt_bn, pool);

  /* Sanity check:  the merge target must be under revision control. */
  SVN_ERR (svn_wc_entry (&entry, merge_target, adm_access, FALSE, pool));
  if (! entry)
    {
      *merge_outcome = svn_wc_merge_no_merge;
      return SVN_NO_ERROR;
    }

  /* Decide if the merge target is a text or binary file. */
  SVN_ERR (svn_wc_has_binary_prop (&is_binary, merge_target, adm_access, pool));
  
  if (! is_binary)              /* this is a text file */
    {
      /* Make sure a temporary copy of 'target' is available with keywords
         contracted and line endings in repository-normal (LF) form.
         This is the file that diff3 will read as the 'mine' file.  */
      SVN_ERR (svn_wc_translated_file (&tmp_target, merge_target, adm_access,
                                       TRUE, pool));
      if (tmp_target == merge_target)  /* contraction didn't happen */
        {
          /* The target is already in repository form, so we just need to
             make a verbatim copy of it. */
          SVN_ERR (svn_io_open_unique_file (&tmp_f, &tmp_target,
                                            merge_target,
                                            SVN_WC__TMP_EXT,
                                            FALSE, pool));
          SVN_ERR (svn_io_file_close (tmp_f, pool));
          SVN_ERR (svn_io_copy_file (merge_target,
                                     tmp_target, TRUE, pool));
        }

      /* Open a second temporary file for writing; this is where diff3
         will write the merged results. */
      SVN_ERR (svn_io_open_unique_file (&result_f, &result_target,
                                        merge_target, SVN_WC__TMP_EXT,
                                        FALSE, pool));

      /* LEFT and RIGHT might be in totally different directories than
         MERGE_TARGET, and our diff3 command wants them all to be in
         the same directory.  So make temporary copies of LEFT and
         RIGHT right next to the target. */
      SVN_ERR (svn_io_open_unique_file (&tmp_f, &tmp_left,
                                        tmp_target,
                                        SVN_WC__TMP_EXT,
                                        FALSE, pool));
      SVN_ERR (svn_io_file_close (tmp_f, pool));
      SVN_ERR (svn_io_open_unique_file (&tmp_f, &tmp_right,
                                        tmp_target,
                                        SVN_WC__TMP_EXT,
                                        FALSE, pool));
      SVN_ERR (svn_io_file_close (tmp_f, pool));
    
      SVN_ERR (svn_io_copy_file (left, tmp_left, TRUE, pool));
      SVN_ERR (svn_io_copy_file (right, tmp_right, TRUE, pool));

      /* Run an external merge if requested. */
      if (diff3_cmd)
        {
          int exit_code;

          SVN_ERR (svn_io_run_diff3 (".",
                                     tmp_target, tmp_left, tmp_right,
                                     target_label, left_label, right_label,
                                     result_f, &exit_code, diff3_cmd, pool));
          
          contains_conflicts = exit_code == 1;
        }
      else
        {
          svn_diff_t *diff;
          const char *target_marker;
          const char *left_marker;
          const char *right_marker;
          svn_stream_t *ostream;

          ostream = svn_stream_from_aprfile(result_f, pool);

          SVN_ERR (svn_diff_file_diff3 (&diff,
                                        tmp_left, tmp_target, tmp_right,
                                        pool));

          /* Labels fall back to sensible defaults if not specified. */
          if (target_label)
            target_marker = apr_psprintf (pool, "<<<<<<< %s", target_label);
          else
            target_marker = "<<<<<<< .working";

          if (left_label)
            left_marker = apr_psprintf (pool, "||||||| %s", left_label);
          else
            left_marker = "||||||| .old";

          if (right_label)
            right_marker = apr_psprintf (pool, ">>>>>>> %s", right_label);
          else
            right_marker = ">>>>>>> .new";

          SVN_ERR (svn_diff_file_output_merge (ostream, diff,
                                               tmp_left, tmp_target, tmp_right,
                                               left_marker,
                                               target_marker,
                                               right_marker,
                                               "=======", /* seperator */
                                               FALSE, /* display original */
                                               FALSE, /* resolve conflicts */
                                               pool));
          SVN_ERR (svn_stream_close (ostream));

          contains_conflicts = svn_diff_contains_conflicts (diff);
        }

      /* Close the output file */
      SVN_ERR (svn_io_file_close (result_f, pool));

      if (contains_conflicts && ! dry_run)  /* got a conflict */
        {
          /* Preserve the three pre-merge files, and modify the
             entry (mark as conflicted, track the preserved files). */ 
          apr_file_t *lcopy_f, *rcopy_f, *tcopy_f;
          const char *left_copy, *right_copy, *target_copy;
          const char *parentt, *left_base, *right_base, *target_base;
          svn_wc_adm_access_t *parent_access;
          svn_wc_entry_t tmp_entry;
      
          /* I miss Lisp. */

          SVN_ERR (svn_io_open_unique_file (&lcopy_f,
                                            &left_copy,
                                            merge_target,
                                            left_label,
                                            FALSE,
                                            pool));
          SVN_ERR (svn_io_file_close (lcopy_f, pool));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -