Some notes about centralized workflow in Git

Basic concepts

  1. Multi-user development need a Central Repo.
  2. Create a bare repo as the central repo: git init --bare central-repo.git. --bare means that we don’t want a working directory. The central repo is only supposed to act as a storage facility–not a development environment.
  3. To access the central repo on a server: ssh://user@example.com/path/to/central-repo.git.
  4. Before pushing local updates to the central repo, we must ensure the history clean as it’s hardly possible to change history after it has been made public. Never rebase commits that have been pushed to a shared repo.
  5. If you need to change a public commit, use the git revert to undo the changes. This creates a new commit with the required modifications instead of re-writing old snapshots.
  6. Git won’t let anyone push to a remote server if it doesn’t result in a fast-forward merge. In order to solve the problem, we can pull in the central changes before trying to push local changes.
  • Get the latest version of the origin/master branch
    $ git fetch origin 
  • Rebase your changes on top of those found in your central repo, i.e. add your changes to whoever else has already done.
    $ git rebase origin/master 
  • After the rebase, your master branch contains everything from the central repo, so you can do a fast-forward push to publish your changes.
    $ git push origin master ## 
  1. The central communication hub condenses all the developments into a single repo and ensures that no one overwrite another’s content.

Quick Reference

git init --bare <repository-name>
Create a Git repository, but omit the working directory.

git remote rm <remote-name>
Remove the specified remote from your bookmarked connections.

Notes from man

  1. git pull = git fetch + git rebase|get merge.

  2. If any of the remote changes overlap with local uncommitted changes, the merge will be automatically canceled and the work tree untouched. It is generally best to get any local changes in working order before pulling or stash them away with git-stash.

  3. NOTE ABOUT FAST-FORWARDS:

    When an update changes a branch (or more in general, a ref) that used to point at commit A to
    point at another commit B, it is called a fast-forward update if and only if B is a descendant of
    A.
    
    In a fast-forward update from A to B, the set of commits that the original commit A built on top
    of is a subset of the commits the new commit B builds on top of. Hence, it does not lose any
    history.
    
    In contrast, a non-fast-forward update will lose history. For example, suppose you and somebody
    else started at the same commit X, and you built a history leading to commit B while the other
    person built a history leading to commit A. The history looks like this:
    
              B
             /
         ---X---A
    
    Further suppose that the other person already pushed changes leading to A back to the original
    repository from which you two obtained the original commit X.
    
    The push done by the other person updated the branch that used to point at commit X to point at
    commit A. It is a fast-forward.
    
    But if you try to push, you will attempt to update the branch (that now points at A) with commit
    B. This does not fast-forward. If you did so, the changes introduced by commit A will be lost,
    because everybody will now start building on top of B.
    
    The command by default does not allow an update that is not a fast-forward to prevent such loss of
    history.
    
    If you do not want to lose your work (history from X to B) or the work by the other person
    (history from X to A), you would need to first fetch the history from the repository, create a
    history that contains changes done by both parties, and push the result back.
    
    You can perform "git pull", resolve potential conflicts, and "git push" the result. A "git pull"
    will create a merge commit C between commits A and B.
    
              B---C
             /   /
         ---X---A
    
    Updating A with the resulting merge commit will fast-forward and your push will be accepted.
    
    Alternatively, you can rebase your change between X and B on top of A, with "git pull --rebase",
    and push the result back. The rebase will create a new commit D that builds the change between X
    and B on top of A.
    
              B   D
             /   /
         ---X---A
    
    Again, updating A with this commit will fast-forward and your push will be accepted.
    
    There is another common situation where you may encounter non-fast-forward rejection when you try
    to push, and it is possible even when you are pushing into a repository nobody else pushes into.
    After you push commit A yourself (in the first picture in this section), replace it with "git
    commit --amend" to produce commit B, and you try to push it out, because forgot that you have
    pushed A out already. In such a case, and only if you are certain that nobody in the meantime
    fetched your earlier commit A (and started building on top of it), you can run "git push --force"
    to overwrite it. In other words, "git push --force" is a method reserved for a case where you do
    mean to lose history.
  4. When git-rebase, All changes made by commits in the current branch but that are not in <upstream> are saved to a temporary area. This is the same set of commits that would be shown by git log <upstream>..HEAD. The commits then reapplied to the current branch, one by one, in order.

本作品采用《CC 协议》,转载必须注明作者和本文链接
日拱一卒
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
92
粉丝
87
喜欢
152
收藏
121
排名:72
访问:11.3 万
私信
所有博文
社区赞助商