threads / discuss / 26588

new behaviour in git merge

Subject: new behaviour in git merge

## tl;dr

8 messages between Feb 24, 2011 and Feb 26, 2011.

replies: 7people: 3as markdown or json

Stephen Rothwell· Feb 24, 2011, 03:33 UTC · lore
Hi all,

I am not sure when this started, but I think git has changed its behaviour when merging. As you all know, I do a lot of merging of trees for linux-next each day. Today I noticed that when I merge a tree, sometimes the timestamps are modified for files that are not modified on one side of the merge. It is not consistent and it is not all the files that are modified on the HEAD side (relative to the merge-base).

For example, today when I merged the drm tree:
$ git merge drm/drm-next
Auto-merging drivers/gpu/drm/drm_info.c
Removing drivers/gpu/drm/i830/Makefile
Removing drivers/gpu/drm/i830/i830_dma.c
Removing drivers/gpu/drm/i830/i830_drv.c
Removing drivers/gpu/drm/i830/i830_drv.h
Removing drivers/gpu/drm/i830/i830_irq.c
Auto-merging drivers/gpu/drm/i915/i915_drv.c
Auto-merging drivers/gpu/drm/i915/i915_drv.h
Auto-merging drivers/gpu/drm/i915/intel_sdvo.c
Auto-merging drivers/gpu/drm/radeon/atombios_crtc.c
Auto-merging drivers/gpu/drm/radeon/evergreen_blit_kms.c
Auto-merging drivers/gpu/drm/radeon/r600.c
Auto-merging drivers/gpu/drm/radeon/r600_blit_kms.c
Auto-merging drivers/gpu/drm/radeon/r600_cs.c
Auto-merging drivers/gpu/drm/radeon/r600d.h
Auto-merging drivers/gpu/drm/radeon/radeon_device.c
Auto-merging drivers/gpu/drm/radeon/radeon_display.c
Auto-merging drivers/gpu/drm/radeon/radeon_mode.h
Auto-merging drivers/gpu/drm/radeon/radeon_ttm.c
Auto-merging drivers/gpu/drm/radeon/rv770.c
Removing include/drm/i830_drm.h
Merge made by recursive.
 drivers/gpu/drm/Kconfig                     |   47 +-
 drivers/gpu/drm/Makefile                    |    3 +-
 drivers/gpu/drm/drm_crtc.c                  |   33 +
 drivers/gpu/drm/drm_drv.c                   |   48 +-
 drivers/gpu/drm/drm_edid.c                  |   19 +-
 drivers/gpu/drm/drm_edid_modes.h            |    4 +-
 drivers/gpu/drm/drm_fb_helper.c             |    5 +
 drivers/gpu/drm/drm_gem.c                   |    5 +-
 drivers/gpu/drm/drm_hashtab.c               |   27 +-
 drivers/gpu/drm/drm_info.c                  |   27 +-
 drivers/gpu/drm/drm_ioctl.c                 |  115 +--
 drivers/gpu/drm/drm_irq.c                   |   14 +-
 drivers/gpu/drm/drm_mm.c                    |  570 ++++++-----
 drivers/gpu/drm/drm_modes.c                 |    6 +-
 drivers/gpu/drm/drm_pci.c                   |  205 ++++-
 drivers/gpu/drm/drm_platform.c              |   75 ++-
 drivers/gpu/drm/drm_stub.c                  |   21 +-
 drivers/gpu/drm/drm_usb.c                   |  117 ++
 drivers/gpu/drm/i810/i810_dma.c             |   18 +-
 drivers/gpu/drm/i810/i810_drv.c             |   20 +-
 drivers/gpu/drm/i830/Makefile               |    8 -
 drivers/gpu/drm/i830/i830_dma.c             | 1560 ---------------------------
 drivers/gpu/drm/i830/i830_drv.c             |  107 --
 drivers/gpu/drm/i830/i830_drv.h             |  295 -----
 drivers/gpu/drm/i830/i830_irq.c             |  186 ----
 drivers/gpu/drm/i915/i915_drv.c             |   23 +-
 drivers/gpu/drm/i915/i915_drv.h             |    7 +
 drivers/gpu/drm/i915/i915_gem.c             |  103 ++-
 drivers/gpu/drm/i915/intel_sdvo.c           |    2 +-
 drivers/gpu/drm/mga/mga_dma.c               |    2 +-
 drivers/gpu/drm/mga/mga_drv.c               |   13 +-
 drivers/gpu/drm/nouveau/nouveau_drv.c       |   21 +-
 drivers/gpu/drm/nouveau/nouveau_mem.c       |    2 +-
 drivers/gpu/drm/nouveau/nouveau_object.c    |    2 +-
 drivers/gpu/drm/nouveau/nouveau_sgdma.c     |   31 +-
 drivers/gpu/drm/nouveau/nouveau_state.c     |    4 +-
 drivers/gpu/drm/nouveau/nv17_tv.c           |    4 +-
 drivers/gpu/drm/nouveau/nv17_tv.h           |    2 +-
 drivers/gpu/drm/nouveau/nv17_tv_modes.c     |    2 +-
 drivers/gpu/drm/nouveau/nv50_instmem.c      |    4 +-
 drivers/gpu/drm/nouveau/nvc0_instmem.c      |    2 +-
 drivers/gpu/drm/r128/r128_drv.c             |   14 +-
 drivers/gpu/drm/radeon/atombios_crtc.c      |    8 +-
 drivers/gpu/drm/radeon/evergreen_blit_kms.c |    2 +-
 drivers/gpu/drm/radeon/r600.c               |    2 +-
 drivers/gpu/drm/radeon/r600_audio.c         |    1 +
 drivers/gpu/drm/radeon/r600_blit_kms.c      |    2 +-
 drivers/gpu/drm/radeon/r600_cs.c            |  353 ++++--
 drivers/gpu/drm/radeon/r600_hdmi.c          |    1 +
 drivers/gpu/drm/radeon/r600d.h              |    5 +
 drivers/gpu/drm/radeon/radeon.h             |   90 +--
 drivers/gpu/drm/radeon/radeon_asic.h        |   77 ++-
 drivers/gpu/drm/radeon/radeon_benchmark.c   |    4 +-
 drivers/gpu/drm/radeon/radeon_cp.c          |    4 +-
 drivers/gpu/drm/radeon/radeon_cs.c          |    2 +-
 drivers/gpu/drm/radeon/radeon_device.c      |    4 +-
 drivers/gpu/drm/radeon/radeon_display.c     |    4 +-
 drivers/gpu/drm/radeon/radeon_drv.c         |   49 +-
 drivers/gpu/drm/radeon/radeon_fb.c          |   12 +-
 drivers/gpu/drm/radeon/radeon_gart.c        |   38 +-
 drivers/gpu/drm/radeon/radeon_gem.c         |   96 ++-
 drivers/gpu/drm/radeon/radeon_kms.c         |    4 +-
 drivers/gpu/drm/radeon/radeon_legacy_crtc.c |    4 +-
 drivers/gpu/drm/radeon/radeon_mode.h        |    1 +
 drivers/gpu/drm/radeon/radeon_object.c      |   28 +-
 drivers/gpu/drm/radeon/radeon_object.h      |    7 +-
 drivers/gpu/drm/radeon/radeon_ring.c        |    4 +-
 drivers/gpu/drm/radeon/radeon_test.c        |    4 +-
 drivers/gpu/drm/radeon/radeon_ttm.c         |   10 +-
 drivers/gpu/drm/radeon/rv770.c              |    2 +-
 drivers/gpu/drm/savage/savage_drv.c         |   14 +-
 drivers/gpu/drm/sis/sis_drv.c               |   13 +-
 drivers/gpu/drm/tdfx/tdfx_drv.c             |   13 +-
 drivers/gpu/drm/ttm/ttm_agp_backend.c       |    3 +-
 drivers/gpu/drm/ttm/ttm_bo.c                |    3 +-
 drivers/gpu/drm/ttm/ttm_page_alloc.c        |   34 +-
 drivers/gpu/drm/ttm/ttm_tt.c                |   12 +-
 drivers/gpu/drm/via/via_drv.c               |   13 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c      |    3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c         |   23 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c         |    5 +-
 include/drm/Kbuild                          |    1 -
 include/drm/drm.h                           |    4 +
 include/drm/drmP.h                          |  120 ++-
 include/drm/drm_crtc.h                      |   13 +-
 include/drm/drm_hashtab.h                   |    6 +-
 include/drm/drm_mm.h                        |   49 +-
 include/drm/drm_mode.h                      |   29 +
 include/drm/drm_usb.h                       |   15 +
 include/drm/i830_drm.h                      |  342 ------
 include/drm/ttm/ttm_bo_driver.h             |    6 +-
 include/drm/ttm/ttm_page_alloc.h            |    8 +-
 92 files changed, 1755 insertions(+), 3565 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_usb.c
 delete mode 100644 drivers/gpu/drm/i830/Makefile
 delete mode 100644 drivers/gpu/drm/i830/i830_dma.c
 delete mode 100644 drivers/gpu/drm/i830/i830_drv.c
 delete mode 100644 drivers/gpu/drm/i830/i830_drv.h
 delete mode 100644 drivers/gpu/drm/i830/i830_irq.c
 create mode 100644 include/drm/drm_usb.h
 delete mode 100644 include/drm/i830_drm.h

Then the timestamps on all these files were updated (this is the list of files rsync has decided to copy - I checked and the timestamps are indeed modified):

Documentation/devicetree/booting-without-of.txt Documentation/devicetree/bindings/eeprom.txt Documentation/devicetree/bindings/marvell.txt Documentation/devicetree/bindings/xilinx.txt Documentation/devicetree/bindings/ata/fsl-sata.txt Documentation/devicetree/bindings/gpio/8xxx_gpio.txt Documentation/devicetree/bindings/gpio/gpio.txt Documentation/devicetree/bindings/gpio/led.txt Documentation/devicetree/bindings/i2c/fsl-i2c.txt Documentation/devicetree/bindings/mmc/fsl-esdhc.txt Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt Documentation/devicetree/bindings/mtd/mtd-physmap.txt Documentation/devicetree/bindings/net/fsl-tsec-phy.txt Documentation/devicetree/bindings/net/mdio-gpio.txt Documentation/devicetree/bindings/net/phy.txt Documentation/devicetree/bindings/net/can/mpc5xxx-mscan.txt Documentation/devicetree/bindings/net/can/sja1000.txt Documentation/devicetree/bindings/pci/83xx-512x-pci.txt Documentation/devicetree/bindings/powerpc/4xx/cpm.txt Documentation/devicetree/bindings/powerpc/4xx/emac.txt Documentation/devicetree/bindings/powerpc/4xx/ndfc.txt Documentation/devicetree/bindings/powerpc/4xx/ppc440spe-adma.txt Documentation/devicetree/bindings/powerpc/4xx/reboot.txt Documentation/devicetree/bindings/powerpc/fsl/board.txt Documentation/devicetree/bindings/powerpc/fsl/diu.txt Documentation/devicetree/bindings/powerpc/fsl/dma.txt Documentation/devicetree/bindings/powerpc/fsl/ecm.txt Documentation/devicetree/bindings/powerpc/fsl/gtm.txt Documentation/devicetree/bindings/powerpc/fsl/guts.txt Documentation/devicetree/bindings/powerpc/fsl/lbc.txt Documentation/devicetree/bindings/powerpc/fsl/mcm.txt Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt Documentation/devicetree/bindings/powerpc/fsl/mpc5121-psc.txt Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt Documentation/devicetree/bindings/powerpc/fsl/mpic.txt Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt Documentation/devicetree/bindings/powerpc/fsl/pmc.txt Documentation/devicetree/bindings/powerpc/fsl/sec.txt Documentation/devicetree/bindings/powerpc/fsl/ssi.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/gpio.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/serial.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/brg.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/i2c.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/pic.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/cpm/usb.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/firmware.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/par_io.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/ucc.txt Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/usb.txt Documentation/devicetree/bindings/powerpc/nintendo/gamecube.txt Documentation/devicetree/bindings/powerpc/nintendo/wii.txt Documentation/devicetree/bindings/spi/fsl-spi.txt Documentation/devicetree/bindings/spi/spi-bus.txt Documentation/devicetree/bindings/usb/fsl-usb.txt Documentation/devicetree/bindings/usb/usb-ehci.txt Documentation/laptops/hpfall.c Documentation/misc-devices/lis3lv02d arch/arm/mach-exynos4/Kconfig arch/arm/mach-exynos4/Makefile.boot arch/arm/mach-exynos4/clock.c arch/arm/mach-exynos4/cpu.c arch/arm/mach-exynos4/cpufreq.c arch/arm/mach-exynos4/dev-audio.c arch/arm/mach-exynos4/dev-pd.c arch/arm/mach-exynos4/dev-sysmmu.c arch/arm/mach-exynos4/dma.c arch/arm/mach-exynos4/gpiolib.c arch/arm/mach-exynos4/headsmp.S arch/arm/mach-exynos4/hotplug.c arch/arm/mach-exynos4/init.c arch/arm/mach-exynos4/irq-combiner.c arch/arm/mach-exynos4/irq-eint.c arch/arm/mach-exynos4/localtimer.c arch/arm/mach-exynos4/mach-smdkc210.c arch/arm/mach-exynos4/mach-smdkv310.c arch/arm/mach-exynos4/mach-universal_c210.c arch/arm/mach-exynos4/platsmp.c arch/arm/mach-exynos4/setup-i2c0.c arch/arm/mach-exynos4/setup-i2c1.c arch/arm/mach-exynos4/setup-i2c2.c arch/arm/mach-exynos4/setup-i2c3.c arch/arm/mach-exynos4/setup-i2c4.c arch/arm/mach-exynos4/setup-i2c5.c arch/arm/mach-exynos4/setup-i2c6.c arch/arm/mach-exynos4/setup-i2c7.c arch/arm/mach-exynos4/setup-sdhci-gpio.c arch/arm/mach-exynos4/setup-sdhci.c arch/arm/mach-exynos4/time.c arch/arm/mach-exynos4/include/mach/debug-macro.S arch/arm/mach-exynos4/include/mach/entry-macro.S arch/arm/mach-exynos4/include/mach/hardware.h arch/arm/mach-exynos4/include/mach/io.h arch/arm/mach-exynos4/include/mach/irqs.h arch/arm/mach-exynos4/include/mach/memory.h arch/arm/mach-exynos4/include/mach/pwm-clock.h arch/arm/mach-exynos4/include/mach/regs-clock.h arch/arm/mach-exynos4/include/mach/regs-irq.h arch/arm/mach-exynos4/include/mach/regs-mem.h arch/arm/mach-exynos4/include/mach/regs-pmu.h arch/arm/mach-exynos4/include/mach/regs-sysmmu.h arch/arm/mach-exynos4/include/mach/smp.h arch/arm/mach-exynos4/include/mach/sysmmu.h arch/arm/mach-exynos4/include/mach/system.h arch/arm/mach-exynos4/include/mach/timex.h arch/arm/mach-exynos4/include/mach/uncompress.h arch/arm/mach-exynos4/include/mach/vmalloc.h arch/arm/mach-msm/devices-iommu.c arch/arm/mach-mx5/devices-imx50.h arch/arm/mach-vt8500/include/mach/vmalloc.h arch/arm/plat-versatile/headsmp.S arch/arm/plat-versatile/localtimer.c drivers/char/virtio_console.c deleting drivers/gpu/drm/i830/i830_irq.c deleting drivers/gpu/drm/i830/i830_drv.h deleting drivers/gpu/drm/i830/i830_drv.c deleting drivers/gpu/drm/i830/i830_dma.c deleting drivers/gpu/drm/i830/Makefile drivers/gpu/drm/Kconfig drivers/gpu/drm/Makefile drivers/gpu/drm/drm_crtc.c drivers/gpu/drm/drm_drv.c drivers/gpu/drm/drm_edid.c drivers/gpu/drm/drm_edid_modes.h drivers/gpu/drm/drm_fb_helper.c drivers/gpu/drm/drm_gem.c drivers/gpu/drm/drm_hashtab.c drivers/gpu/drm/drm_info.c drivers/gpu/drm/drm_ioctl.c drivers/gpu/drm/drm_irq.c drivers/gpu/drm/drm_mm.c drivers/gpu/drm/drm_modes.c drivers/gpu/drm/drm_pci.c drivers/gpu/drm/drm_platform.c drivers/gpu/drm/drm_stub.c drivers/gpu/drm/drm_usb.c drivers/gpu/drm/i810/i810_dma.c drivers/gpu/drm/i810/i810_drv.c drivers/gpu/drm/i915/i915_drv.c drivers/gpu/drm/i915/i915_drv.h drivers/gpu/drm/i915/i915_gem.c drivers/gpu/drm/i915/intel_sdvo.c drivers/gpu/drm/mga/mga_dma.c drivers/gpu/drm/mga/mga_drv.c drivers/gpu/drm/nouveau/nouveau_drv.c drivers/gpu/drm/nouveau/nouveau_mem.c drivers/gpu/drm/nouveau/nouveau_object.c drivers/gpu/drm/nouveau/nouveau_sgdma.c drivers/gpu/drm/nouveau/nouveau_state.c drivers/gpu/drm/nouveau/nv17_tv.c drivers/gpu/drm/nouveau/nv17_tv.h drivers/gpu/drm/nouveau/nv17_tv_modes.c drivers/gpu/drm/nouveau/nv50_instmem.c drivers/gpu/drm/nouveau/nvc0_instmem.c drivers/gpu/drm/r128/r128_drv.c drivers/gpu/drm/radeon/atombios_crtc.c drivers/gpu/drm/radeon/evergreen_blit_kms.c drivers/gpu/drm/radeon/r600.c drivers/gpu/drm/radeon/r600_audio.c drivers/gpu/drm/radeon/r600_blit_kms.c drivers/gpu/drm/radeon/r600_cs.c drivers/gpu/drm/radeon/r600_hdmi.c drivers/gpu/drm/radeon/r600d.h drivers/gpu/drm/radeon/radeon.h drivers/gpu/drm/radeon/radeon_asic.h drivers/gpu/drm/radeon/radeon_benchmark.c drivers/gpu/drm/radeon/radeon_cp.c drivers/gpu/drm/radeon/radeon_cs.c drivers/gpu/drm/radeon/radeon_device.c drivers/gpu/drm/radeon/radeon_display.c drivers/gpu/drm/radeon/radeon_drv.c drivers/gpu/drm/radeon/radeon_fb.c drivers/gpu/drm/radeon/radeon_gart.c drivers/gpu/drm/radeon/radeon_gem.c drivers/gpu/drm/radeon/radeon_kms.c drivers/gpu/drm/radeon/radeon_legacy_crtc.c drivers/gpu/drm/radeon/radeon_mode.h drivers/gpu/drm/radeon/radeon_object.c drivers/gpu/drm/radeon/radeon_object.h drivers/gpu/drm/radeon/radeon_ring.c drivers/gpu/drm/radeon/radeon_test.c drivers/gpu/drm/radeon/radeon_ttm.c drivers/gpu/drm/radeon/rv770.c drivers/gpu/drm/savage/savage_drv.c drivers/gpu/drm/sis/sis_drv.c drivers/gpu/drm/tdfx/tdfx_drv.c drivers/gpu/drm/ttm/ttm_agp_backend.c drivers/gpu/drm/ttm/ttm_bo.c drivers/gpu/drm/ttm/ttm_page_alloc.c drivers/gpu/drm/ttm/ttm_tt.c drivers/gpu/drm/via/via_drv.c drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c drivers/gpu/drm/vmwgfx/vmwgfx_drv.c drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c drivers/misc/lis3lv02d/lis3lv02d.c drivers/misc/lis3lv02d/lis3lv02d.h drivers/misc/lis3lv02d/lis3lv02d_i2c.c drivers/misc/lis3lv02d/lis3lv02d_spi.c drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c drivers/net/wireless/iwlegacy/iwl-3945-fh.h drivers/net/wireless/iwlegacy/iwl-3945-hw.h drivers/net/wireless/iwlegacy/iwl-3945-rs.c drivers/net/wireless/iwlegacy/iwl-3945.c drivers/net/wireless/iwlegacy/iwl-3945.h drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c drivers/net/wireless/iwlegacy/iwl-4965-hw.h drivers/net/wireless/iwlegacy/iwl-4965-led.c drivers/net/wireless/iwlegacy/iwl-4965.c drivers/net/wireless/iwlegacy/iwl3945-base.c drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h drivers/net/wireless/rtlwifi/rtl8192cu/rf.h drivers/platform/x86/hp_accel.c drivers/scsi/fcoe/fcoe_ctlr.c drivers/watchdog/m54xx_wdt.c deleting include/drm/i830_drm.h include/drm/Kbuild include/drm/drm.h include/drm/drmP.h include/drm/drm_crtc.h include/drm/drm_hashtab.h include/drm/drm_mm.h include/drm/drm_mode.h include/drm/drm_usb.h include/drm/ttm/ttm_bo_driver.h include/drm/ttm/ttm_page_alloc.h include/linux/hid-roccat.h include/linux/i2c-tegra.h include/linux/i2c/atmel_mxt_ts.h include/media/s5p_fimc.h net/bluetooth/l2cap_core.c

I am pretty sure that git did not used to do this. Has anyone else seen this? I am running git version 1.7.4.1 from Debian unstable.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
Jeff King· Feb 24, 2011, 08:15 UTC · re: Stephen Rothwell · lore

Re: new behaviour in git merge

On Thu, Feb 24, 2011 at 02:33:53PM +1100, Stephen Rothwell wrote:
Show 11 quoted lines
> I am not sure when this started, but I think git has changed its behaviour
> when merging.   As you all know, I do a lot of merging of trees for
> linux-next each day.  Today I noticed that when I merge a tree, sometimes
> the timestamps are modified for files that are not modified on one side
> of the merge.  It is not consistent and it is not all the files that are
> modified on the HEAD side (relative to the merge-base).
>
> [...]
>
> I am pretty sure that git did not used to do this. Has anyone else seen
> this?  I am running git version 1.7.4.1 from Debian unstable.

I don't think any such change was intentional. I couldn't reproduce with a trivial example. Can you give the commit IDs of the two heads in your example merge? I'd like to try bisecting if I can reproduce the issue.

-Peff
Stephen Rothwell· Feb 24, 2011, 09:24 UTC · re: Jeff King · lore

Re: new behaviour in git merge

Hi Jeff,
On Thu, 24 Feb 2011 03:15:53 -0500 Jeff King <peff@peff.net> wrote:
>
> I don't think any such change was intentional.  I couldn't reproduce
I was hoping that it was not intentional :-)
> with a trivial example. Can you give the commit IDs of the two heads in
I also tried a trivial example but failed to reproduce it.
> your example merge? I'd like to try bisecting if I can reproduce the
> issue.

In today's linux-next tree (available at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git), commit ad11c1e8abca18872c2993b09b1abde418955b6c is just before the merge and commit a2c06ee2fe5b48a71e697bae00c6e7195fc016b6 is what was merged.

I just did this in a copy of my tree:
	git reset --hard ad11c1e8abca18872c2993b09b1abde418955b6c
	sleep 90
	git merge a2c06ee2fe5b48a71e697bae00c6e7195fc016b6

A comparison of the ls -lR ouput before and after showed a lot of changed modification times.

Several other merges showed the same problem.
Thanks for looking at this.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
Jeff King· Feb 24, 2011, 11:52 UTC · re: Stephen Rothwell · lore

Re: new behaviour in git merge

[+cc Elijah Newren; this is a bug that bisects to one of your commits.
 The backstory is that during a merge, many unrelated files get
 unnecessarily re-written with the same content. Read on for details.]
On Thu, Feb 24, 2011 at 08:24:54PM +1100, Stephen Rothwell wrote:
Show 15 quoted lines
> In today's linux-next tree (available at
> git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git),
> commit ad11c1e8abca18872c2993b09b1abde418955b6c is just before the merge
> and commit a2c06ee2fe5b48a71e697bae00c6e7195fc016b6 is what was merged.
> 
> I just did this in a copy of my tree:
> 
> 	git reset --hard ad11c1e8abca18872c2993b09b1abde418955b6c
> 	sleep 90
> 	git merge a2c06ee2fe5b48a71e697bae00c6e7195fc016b6
> 
> A comparison of the ls -lR ouput before and after showed a lot of changed
> modification times.
> 
> Several other merges showed the same problem.

Thanks for the reproduction recipe. I was able to bisect using this script as my test:

-- >8 -- #!/bin/sh

stat() {
  git ls-files -z | xargs --null stat --format='%Y %n' | sort
}
cd linux-next &&
git reset --hard ad11c1e8abca18872c2993b09b1abde418955b6c &&
sleep 3 &&
stat >before &&
git merge a2c06ee2fe5b48a71e697bae00c6e7195fc016b6 &&
stat >after &&
comm -13 before after | cut -d' ' -f2 | sort >stat-diff &&
git diff-tree -r --name-only HEAD HEAD^ >tree-diff &&
comm -23 stat-diff tree-diff >extra-stats &&
if test -s extra-stats; then
  cat extra-stats
  echo FAIL
  exit 1
else
  echo OK
  exit 0
fi
-- 8< --

It bisects to 882fd11 (merge-recursive: Delay content merging for renames, 2010-09-20). And indeed, looking further at the files that get modified, they appear to be renames on one side of the merge, but not touched on the other side. But rather than notice that there is nothing to be done on them, we seem to update the index and write out the new entries.

The patch below makes the problem go away in your test case, but also introduces some test failures in t3509, so I'm sure there is something else going on. I'm somewhat clueless about the merge code, so I'll defer to Elijah, who wrote 882fd11, and see what he says.

-Peff
diff --git a/merge-recursive.c b/merge-recursive.c
index 0ca54bd..1dd643f 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1083,7 +1083,8 @@ static int process_renames(struct merge_options *o,
 					b = ren1->pair->two;
 					a = &src_other;
 				}
-				update_stages_and_entry(ren1_dst, ren1->dst_entry, one, a, b, 1);
+				if (hashcmp(one->sha1, b->sha1))
+					update_stages_and_entry(ren1_dst, ren1->dst_entry, one, a, b, 1);
 				if (string_list_has_string(&o->current_directory_set, ren1_dst)) {
 					setup_rename_df_conflict_info(RENAME_NORMAL,
 								      ren1->pair,
Elijah Newren· Feb 26, 2011, 18:34 UTC · re: Jeff King · lore

[RFC PATCH 0/2] Fix unnecessary updates of files during merge

This patch series adds a simple testcase demonstrating the problem reported by Stephen Rothwell, and a fix. Unfortunately, there's a bug with the fix (hence the RFC) that makes the relevant files racily clean rather than clearly clean (i.e. 'git diff-files' will report these files as modified when it shouldn't).

I'll try to figure out how to fix the second problem in the next few days. If anyone has some hints, I'm all ears.

Elijah Newren (2):
  t6022: New test checking for unnecessary updates of renamed+modified
    files
  merge-recursive: When we detect we can skip an update, actually skip
    it
 merge-recursive.c       |    7 +++++--
 t/t6022-merge-rename.sh |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 2 deletions(-)
-- 
1.7.4.1.23.g4865dd
Elijah Newren· Feb 26, 2011, 18:34 UTC · re: Elijah Newren · lore

[RFC PATCH 1/2] t6022: New test checking for unnecessary updates of renamed+modified files

Signed-off-by: Elijah Newren <newren@gmail.com>
---
 t/t6022-merge-rename.sh |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh
index 1ed259d..71bfd22 100755
--- a/t/t6022-merge-rename.sh
+++ b/t/t6022-merge-rename.sh
@@ -609,4 +609,36 @@ test_expect_success 'check handling of differently renamed file with D/F conflic
 	! test -f original
 '
 
+test_expect_success 'setup avoid unnecessary update' '
+	git reset --hard &&
+	git checkout --orphan avoid-unnecessary-update &&
+	git rm -rf . &&
+	git clean -fdqx &&
+
+	printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original &&
+	git add -A &&
+	git commit -m "Common commmit" &&
+
+	git mv original rename &&
+	echo 11 >>rename &&
+	git add -u &&
+	git commit -m "Renamed and modified" &&
+
+	git checkout -b other-branch HEAD~1 &&
+	echo "random content" >random-file &&
+	git add -A &&
+	git commit -m "Random, unrelated changes"
+'
+
+test_expect_failure 'avoid unnecessary update' '
+	git checkout -q avoid-unnecessary-update^0 &&
+	orig=$(stat --format="%Y" rename) &&
+	sleep 1 &&
+	git merge other-branch &&
+	new=$(stat --format="%Y" rename) &&
+	echo "Checking whether stat times are same: $orig vs $new" &&
+	test "$orig" == "$new" &&
+	git diff-files --exit-code # Is "rename" clean, or only racily clean?
+'
+
 test_done
-- 
1.7.4.1.23.g4865dd
Elijah Newren· Feb 26, 2011, 18:34 UTC · re: Elijah Newren · lore

[RFC PATCH 2/2] merge-recursive: When we detect we can skip an update, actually skip it

In 882fd11 (merge-recursive: Delay content merging for renames 2010-09-20), the code that checked for whether we could skip updating a file in the working directory (due to the merged version matching the current copy) was moved into a separate function. In order to defer the content merging, we had to update the index with unmerged entries. As part of the move, a bug was introduced such that the message about skipping the update would be printed (if GIT_MERGE_VERBOSITY was sufficiently high) but the file would be updated in the working copy anyway.

When we detect that the file does not need to be updated in the working copy, update the index to remove the unmerged entries and then return early before updating the working copy.

STILL BROKEN: Unfortunately, this change leaves the index in a state where the renamed file is only racily clean; a 'git diff-files' will report the file as modified.

--- No Signed-off-by since it still doesn't work.

 merge-recursive.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index 16c2dbe..94b818c 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1274,9 +1274,12 @@ static int merge_content(struct merge_options *o,
 	}
 
 	if (mfi.clean && !df_conflict_remains &&
-	    sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode)
+	    sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode) {
 		output(o, 3, "Skipped %s (merged same as existing)", path);
-	else
+		add_cacheinfo(mfi.mode, mfi.sha, path,
+			      0, 0, ADD_CACHE_OK_TO_REPLACE);
+		return mfi.clean;
+	} else
 		output(o, 2, "Auto-merging %s", path);
 
 	if (!mfi.clean) {
-- 
1.7.4.1.23.g4865dd
Elijah Newren· Feb 26, 2011, 18:43 UTC · re: Elijah Newren · lore

Re: [RFC PATCH 0/2] Fix unnecessary updates of files during merge

Hi,
On Sat, Feb 26, 2011 at 11:34 AM, Elijah Newren <newren@gmail.com> wrote:
Show 8 quoted lines
> This patch series adds a simple testcase demonstrating the problem
> reported by Stephen Rothwell, and a fix.  Unfortunately, there's a bug
> with the fix (hence the RFC) that makes the relevant files racily clean
> rather than clearly clean (i.e. 'git diff-files' will report these files
> as modified when it shouldn't).
>
> I'll try to figure out how to fix the second problem in the next few
> days.  If anyone has some hints, I'm all ears.
And, of course, I forgot to include the cc's in my send-email command.
 Sorry about that, Stephen and Jeff.  Adding you on this email, at
least.
Show 9 quoted lines
> Elijah Newren (2):
>  t6022: New test checking for unnecessary updates of renamed+modified
>    files
>  merge-recursive: When we detect we can skip an update, actually skip
>    it
>
>  merge-recursive.c       |    7 +++++--
>  t/t6022-merge-rename.sh |   32 ++++++++++++++++++++++++++++++++
>  2 files changed, 37 insertions(+), 2 deletions(-)

← back to recent threads