所以我有一个差异补丁,我希望逐行覆盖在原始代码片段上,但我遇到的问题是将正确的原始行号与diff补丁中的行匹配。
例如,假设我有以下补丁:
> @diff_lines
=> ["@@ -1827,7 +1827,7 @@ def has_and_belongs_to_many(name, scope = nil, **options, &extension)\n",
" \n",
" builder = Builder::HasAndBelongsToMany.new name, self, options\n",
" \n",
"- join_model = builder.through_model\n",
"+ join_model = ActiveSupport::Deprecation.silence { builder.through_model }\n",
" \n",
" const_set join_model.name, join_model\n",
" private_constant join_model.name\n"]
我需要在原始代码中查找的行是join_model = builder.through_model\n",
。
根据大块范围信息,我查看第1830行(即1827 + 3),因为修改中通常包含3行(之前和之后)。
但是,如果你计算补丁顶部的线条,包括第一行,换行符和删除的行有5行...但是在添加换行符后,有4行,包括在补丁结束前添加的换行符。
所以我还没有找到一种数学方法来查看补丁并直接转到与大块范围信息相对应的行。
或者更棘手的是this diff,其中更改与空间相关,并且大块范围似乎没有指定每个更改所在的行。
以下是该代码段:
> d2.first.patch.lines
=> ["@@ -158,33 +158,33 @@ def synchronize(&block)\n",
" @lock.synchronize(&block)\n",
" end\n",
" \n",
"- # Test if the queue currently contains any elements.\n",
"+ # Test if the queue currently contains any elements.\n",
" def any?\n",
" !@queue.empty?\n",
" end\n",
" \n",
"- # A thread can remove an element from the queue without\n",
"- # waiting if and only if the number of currently available\n",
"- # connections is strictly greater than the number of waiting\n",
"- # threads.\n",
"+ # A thread can remove an element from the queue without\n",
"+ # waiting if and only if the number of currently available\n",
"+ # connections is strictly greater than the number of waiting\n",
"+ # threads.\n",
" def can_remove_no_wait?\n",
" @queue.size > @num_waiting\n",
" end\n",
" \n",
"- # Removes and returns the head of the queue if possible, or nil.\n",
"+ # Removes and returns the head of the queue if possible, or nil.\n",
" def remove\n",
" @queue.shift\n",
" end\n",
" \n",
"- # Remove and return the head the queue if the number of\n",
"- # available elements is strictly greater than the number of\n",
"- # threads currently waiting. Otherwise, return nil.\n",
"+ # Remove and return the head the queue if the number of\n",
"+ # available elements is strictly greater than the number of\n",
"+ # threads currently waiting. Otherwise, return nil.\n",
" def no_wait_poll\n",
" remove if can_remove_no_wait?\n",
" end\n",
" \n",
"- # Waits on the queue up to +timeout+ seconds, then removes and\n",
"- # returns the head of the queue.\n",
"+ # Waits on the queue up to +timeout+ seconds, then removes and\n",
"+ # returns the head of the queue.\n",
" def wait_poll(timeout)\n",
" @num_waiting += 1\n",
" \n",
"@@ -582,8 +582,8 @@ def num_waiting_in_queue # :nodoc:\n",
" end\n",
" \n",
" private\n",
"- #--\n",
"- # this is unfortunately not concurrent\n",
"+ #--\n",
"+ # this is unfortunately not concurrent\n",
" def bulk_make_new_connections(num_new_conns_needed)\n",
" num_new_conns_needed.times do\n",
" # try_to_checkout_new_connection will not exceed pool's @size limit\n",
"@@ -594,19 +594,19 @@ def bulk_make_new_connections(num_new_conns_needed)\n",
" end\n",
" end\n",
" \n",
"- #--\n",
"- # From the discussion on GitHub:\n",
"- # https://github.com/rails/rails/pull/14938#commitcomment-6601951\n",
"- # This hook-in method allows for easier monkey-patching fixes needed by\n",
"- # JRuby users that use Fibers.\n",
"+ #--\n",
"+ # From the discussion on GitHub:\n",
"+ # https://github.com/rails/rails/pull/14938#commitcomment-6601951\n",
"+ # This hook-in method allows for easier monkey-patching fixes needed by\n",
"+ # JRuby users that use Fibers.\n",
" def connection_cache_key(thread)\n",
" thread\n",
" end\n",
" \n",
"- # Take control of all existing connections so a \"group\" action such as\n",
"- # reload/disconnect can be performed safely. It is no longer enough to\n",
"- # wrap it in +synchronize+ because some pool's actions are allowed\n",
"- # to be performed outside of the main +synchronize+ block.\n",
"+ # Take control of all existing connections so a \"group\" action such as\n",
"+ # reload/disconnect can be performed safely. It is no longer enough to\n",
"+ # wrap it in +synchronize+ because some pool's actions are allowed\n",
"+ # to be performed outside of the main +synchronize+ block.\n",
" def with_exclusively_acquired_all_connections(raise_on_acquisition_timeout = true)\n",
" with_new_connections_blocked do\n",
" attempt_to_checkout_all_existing_connections(raise_on_acquisition_timeout)\n",
"@@ -658,8 +658,8 @@ def attempt_to_checkout_all_existing_connections(raise_on_acquisition_timeout =\n",
" end\n",
" end\n",
" \n",
"- #--\n",
"- # Must be called in a synchronize block.\n",
"+ #--\n",
"+ # Must be called in a synchronize block.\n",
" def checkout_for_exclusive_access(checkout_timeout)\n",
" checkout(checkout_timeout)\n",
" rescue ConnectionTimeoutError\n",
"@@ -690,17 +690,17 @@ def with_new_connections_blocked\n",
" synchronize { @new_cons_enabled = previous_value }\n",
" end\n",
" \n",
"- # Acquire a connection by one of 1) immediately removing one\n",
"- # from the queue of available connections, 2) creating a new\n",
"- # connection if the pool is not at capacity, 3) waiting on the\n",
"- # queue for a connection to become available.\n",
"- #\n",
"- # Raises:\n",
"- # - ActiveRecord::ConnectionTimeoutError if a connection could not be acquired\n",
"- #\n",
"- #--\n",
"- # Implementation detail: the connection returned by +acquire_connection+\n",
"- # will already be \"+connection.lease+ -ed\" to the current thread.\n",
"+ # Acquire a connection by one of 1) immediately removing one\n",
"+ # from the queue of available connections, 2) creating a new\n",
"+ # connection if the pool is not at capacity, 3) waiting on the\n",
"+ # queue for a connection to become available.\n",
"+ #\n",
"+ # Raises:\n",
"+ # - ActiveRecord::ConnectionTimeoutError if a connection could not be acquired\n",
"+ #\n",
"+ #--\n",
"+ # Implementation detail: the connection returned by +acquire_connection+\n",
"+ # will already be \"+connection.lease+ -ed\" to the current thread.\n",
" def acquire_connection(checkout_timeout)\n",
" # NOTE: we rely on +@available.poll+ and +try_to_checkout_new_connection+ to\n",
" # +conn.lease+ the returned connection (and to do this in a +synchronized+\n",
"@@ -716,8 +716,8 @@ def acquire_connection(checkout_timeout)\n",
" end\n",
" end\n",
" \n",
"- #--\n",
"- # if owner_thread param is omitted, this must be called in synchronize block\n",
"+ #--\n",
"+ # if owner_thread param is omitted, this must be called in synchronize block\n",
" def remove_connection_from_thread_cache(conn, owner_thread = conn.owner)\n",
" @thread_cached_conns.delete_pair(connection_cache_key(owner_thread), conn)\n",
" end\n",
"@@ -729,11 +729,11 @@ def new_connection\n",
" end\n",
" end\n",
" \n",
"- # If the pool is not at a +@size+ limit, establish new connection. Connecting\n",
"- # to the DB is done outside main synchronized section.\n",
"- #--\n",
"- # Implementation constraint: a newly established connection returned by this\n",
"- # method must be in the +.leased+ state.\n",
"+ # If the pool is not at a +@size+ limit, establish new connection. Connecting\n",
"+ # to the DB is done outside main synchronized section.\n",
"+ #--\n",
"+ # Implementation constraint: a newly established connection returned by this\n",
"+ # method must be in the +.leased+ state.\n",
" def try_to_checkout_new_connection\n",
" # first in synchronized section check if establishing new conns is allowed\n",
" # and increment @now_connecting, to prevent overstepping this pool's @size"]