2

Apologies for the double post, but I wasn't getting any further replies in my previous question, so thought I'd try my luck explaining it better ...

I've set my git working structure as follows (thanks to a recommendation in another question git : Small project work)

 /live/website
       |
       |
/path/to/staging (bare)
  |          |
  |          |
dev1        dev2

Currently, both dev1 and dev2, push the projects to the /path/to/staging repo. I have a hook in /path/to/staging, that automatically triggers a cd /live/website && git pull from my /path/to/staging. This way, I have a working copy of all files there. So really dev1, dev2 and /live/website are git clones of /path/to/staging.

Rudi, recommended finding out if receive.denyNonFastforwards was set to true on path/to/staging by doing:

cd path/to/staging/ && git config --get-all receive.denyNonFastforwards

And unfortunately it is set to true. So for example if I did a git reset --hard <SHA-1> on the /live/website server, it does so successfully. However, when I try to push my changes from /live/website to /path/to/staging:

error: failed to push some refs to '/path/to/staging/' To prevent you from losing history, non-fast-forward updates were rejected. Merge the remote changes before pushing again. See the 'non-fast-forward'

Assumably, I face the same problem when I make the changes within dev1 or dev2 and try to push the changes to /path/to/staging.

I want to have a kind of master reset where I could just log onto /path/to/staging or /live/website and step-down to a stable version instead of figuring out which developer made the change and then doing a git reset. Can this be done? I basically want to have the ability to step down to a different version of a file, if I choose to do so ...

5
  • possible duplicate of git hook permission problem
    – Cascabel
    Commented Dec 9, 2010 at 17:33
  • 1
    First of all, the time in which you were disappointed by the lack of replies was nighttime in the US. Have some patience. Second, if you really are not getting what you need, edit and clean up your old question. (From a quick read, it's pretty hard to tell what you're asking.) That pushes it back up in the list. There is never any reason to repost a question here.
    – Cascabel
    Commented Dec 9, 2010 at 17:34
  • 1
    you should never try to remove history. create revert commits (with git revert) for the faulty commits, to get back to a good state. using reset sounds like an awfully bad workflow
    – knittl
    Commented Dec 9, 2010 at 17:53
  • Jefromi, I wasn't complaining about the lack of replies. This is a voluntary service and I really appreciate it. I'm extremely thankful to any and all help I receive. I just thought it was probably my explanation within comments that didn't seem readable, thus I made a new topic.
    – g1t
    Commented Dec 9, 2010 at 19:12
  • Knittl, thanks for the heads-up, I was aware that its safer not to resort to it. However, revert is another good roll-back option ...
    – g1t
    Commented Dec 9, 2010 at 19:14

1 Answer 1

1

From your other questions I guess your situation looks like line 1 in the following diagram.

    current workflow:
                     /live/website    /path/to/staging     dev
1   now              1-2-3-F          1-2-3-F              1-2-3-F
2   reko             1-2-3(-F rm) ->  1-2-3                1-2-3-F
3   hack hack hack   1-2-3            1-2-3                1-2-3-F-5-6-7
4   dev push         1-2-3            1-2-3-F-5-6-7 <-     1-2-3-F-5-6-7
5   auto update      1-2-3-F-5-6-7 <- 1-2-3-F-5-6-7        1-2-3-F-5-6-7

6   revert workflow:
7   now              1-2-3-F          1-2-3-F              1-2-3-F
8   backout          1-2-3-F-~F   ->  1-2-3-F-~F           1-2-3-F
9   hack hack hack   1-2-3-F-~F       1-2-3-F-~F           1-2-3-F-5-6-7
10  dev try push     1-2-3-F-~F       1-2-3-F-~F           1-2-3-F-5-6-7
11  dev pull         1-2-3-F-~F       1-2-3-F-~F       ->  1-2-3-F-5-6-7-8
                                                                \-~F--/

12  dev push         1-2-3-F-~F       1-2-3-F-5-6-7-8  <-  1-2-3-F-5-6-7-8
                                             \-~F--/              \-~F--/

13  auto update      1-2-3-F-5-6-7-8  1-2-3-F-5-6-7-8  <-  1-2-3-F-5-6-7-8
                            \-~F--/          \-~F--/              \-~F--/

In your current workflow you have one defect top commit(F) which you remove(2) with rebase or reset, and then push this removed commit into the central repository. The problems of this workflow arise, when the developer which introduced F did other commits(4) on top of F(which is the default behavior in git), and then pushes this work again. Since the F commit was only stripped from the central repo the developer does not know that F should not be there, and so F reappears(4). Since you set up a hook on the central repo which automatically updates /live/website this means that after this push the fault also reappears on the webside. It's now even worse, because F now is not the HEAD anymore, so you can't easily remove F (you can rebase now, but the problem that F lives in a developer repo is still there).

In the revert workflow you tell git revert F(8), which causes git to create a commit which undoes commit F, here called ~F. Your working copy is now at a state which looks as if F never happened, and you can safely push ~F to the central repository. Now when the other developer has new work done and want to push(10), git will refuse this push, since the ~F commit in the central repository is not an ancestor of any commits in the developers repository, and git now forces the developer to pull ~F from the central repository(11). Then the developer must merge (or rebase) ~F into his branch(12), before the new changes can be pushed to the central repo again(13).

One word about the /live/website repo: Since you have a hook in /path/to/staging which automatically updates this repo on a push, it is not a good idea to do changes in /live/website. The main problem is that if you have local changed files there, or commits which cause merge conflicts, the push-hook in /path/to/staging can fail and leave /live/website in a very ugly state. In a scenario with automatic updates it is better to give the ownership of the directory directly to the updating machinery, which means all file changes there should only come from a git pull, but not from direct edits/commits in there. You can do corrections in a clone of /live/website, and then push these changes into /path/to/staging, which then distributes your changes back to /live/website (but do not push into /live/website[which cause git to screw up your index], nor do pull your clone changes in there, because then you may need to merge different development histories from your clone and /path/to/staging in /live/website, which is definitely not what you want).

1
  • Thanks a lot Rudi for the extensive post! Like always, much appreciated!
    – g1t
    Commented Dec 12, 2010 at 23:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.