0

I'm struggling to get this to work, most likely because of a lack of understanding of what each command is actually responsible for.

I have:

  • "A", a bare repo
  • "B" cloned from "A" (it should maybe be a branch in "A," instead, but let's start with this use case.) Initially, it was cloned as bare, but when merging, I need to have a working copy.
  • "B" never pushes to "A"

Scenario:

  1. "A" gets whole 9 yards updated including dir 'Z'
  2. "B" had just one dir 'Z' changed

I want to:

  1. pull all changes from remote "A", except 'Z'
  2. keep changes from "B" made in 'Z' over those from "A" in any revision.

I've already tried to accomplish this by doing the following.

in "B":

  1. git fetch -a -t origin
  2. git merge --no-commit --no-ff TAG
  3. git reset Z
  4. git commit

It doesn't work.

  1. git pull --rebase origin master

Still updates 'Z', so I don't know where to reset 'Z'.

Kyle Kelley
  • 13,804
  • 8
  • 49
  • 78
bua
  • 4,761
  • 1
  • 26
  • 32

2 Answers2

2

Instead of git reset, you'll want to use git checkout in step 3:

  1. git fetch -a -t origin
  2. git merge --no-commit --no-ff TAG
  3. git checkout HEAD -- Z/
  4. git commit

In general, git checkout is the way to say "make something in my working copy look like the reference I describe," whether it's your entire working copy, a file, or a subdirectory. That's exactly what you want here: during the merge, you want to say "scrap any changes that were merged in, and instead make directory Z look exactly like it does in HEAD". (Remember that HEAD hasn't moved yet because the merge hasn't been committed!)

git reset is generally used for manipulating some subset of HEAD, the index (changes that you've staged for commit), and the working copy together to some state. Reset can be confusing, but there's a good, in-depth write-up on git-scm.com if you want more information.

Ash Wilson
  • 22,820
  • 3
  • 34
  • 45
  • Hey Ash, on git merge --no-commit --no-ff origin/maseter i get: merge: origin(or any combination I put) - not something we can merge, could you advice on this one? – bua Oct 31 '13 at 08:53
  • ok i used FETCH_HEAD instead of 'origin/master', something worked, but I'm so confused about what it actually did (not sure is it correct now..) – bua Oct 31 '13 at 08:59
  • Oh, `origin/master` is the ref that I used in my testing sandbox -- your repository might be set up differently. You can keep steps 1 and 2 the same as you were doing to merge in a tag. (Actually, let me edit it that way -- it'll be less confusing.) – Ash Wilson Oct 31 '13 at 13:21
  • Also, as an explanation: each time you run `git fetch`, the "remote tracking branches" (`origin/master`, `origin/foo`...) are brought up to date with their states on the corresponding remote. So `git fetch` made `origin/master` the same as the `master` branch on my `origin` remote, which I then merged to bring in the new work from `origin`. I'm not sure why you saw the error you did -- did you put a space in between `origin` and `master`? The remote tracking branches your repo knows about should appear in the output of `git branch -a`. – Ash Wilson Oct 31 '13 at 13:27
  • my remote is actually named `origin` and i want use `master` branch. But it somehow doesn't recognize it... There's one strange thing: `git fetch -a -t` #doesn't gets all necessary stuff ... `git merge --no... FETCH_HEAD` says: Already up-to-date need to run: `git fetch` only then `git merge ... F_H` does some work Thanks for informative answer btw! and the link... – bua Oct 31 '13 at 13:31
  • @bua: Actually, on some further reading, it looks like giving the `-t` switch to `git fetch` causes git to fetch *only* tags from each remote, so you wouldn't update `origin/master` at all! Try a simple `git fetch` with no arguments. Reference: https://www.kernel.org/pub/software/scm/git/docs/git-fetch.html – Ash Wilson Oct 31 '13 at 13:34
0

So if i got your question correct you should git checkout -b newbranch on B to get all your changes in a new branch and git commit them.

After committing your changes you can now switch back to master and do git fetch -a origin && git merge origin/master. Above command will merge in all changes from A onto B.

Following the merge you can use git rebase master newbranch to get all your changes on B from before and rebase them onto changes from A.

Learath2
  • 20,023
  • 2
  • 20
  • 30