Конфигурирование nginx+fpm

Nginx and PHP-FPM Configuration and Optimizing Tips and Tricks

I wrote before a guide Howto install Nginx/PHP-FPM on Fedora 20/19, CentOS/RHEL 6.5/5.10, but this guide is just installation guide and many cases Nginx and PHP-FPM basic configuration is good enough, but if you want to squeeze all the juice out of your VPS or web server / servers and do your maintenance work little bit easier, then this guide might be useful. These tips are based entirely on my own experience, so they may not be an absolute truth, and in some situations, a completely different configuration may work better. It’s also good to remember leave resources for another services also if you run example, MySQL, PostgreSQL, MongoDB, Mail server, Name server and/or SSH server on same machine.

And yes here we go…

Nginx Configuration and Optimizing Tips and Tricks

Nginx Tip 1. – Organize Nginx Configuration Files

Normally Nginx configuration files are located under /etc/nginx path.
One good way to organize configuration files is use Debian/Ubuntu Apache style setup:

Virtualhost files have 2 paths, because sites-available directory can contain any stuff, like test configs, just copied/created configs, old configs and so on. And sites-enabled contains only really enabled configurations, actually just only symbolic links to sites-available directory.

Remember add following includes at the end of your nginx.conf file:

Nginx Tip 2. – Determine Nginx worker_processes and worker_connections

Default setup is okay for worker_processes and worker_connections, but these values could be little bit optimized:
max_clients = worker_processes * worker_connections

Just Nginx basic setup can handle hundreds of concurrent connection:

Normally 1000 concurrent connection / per one server is good, but sometimes other parts like disks on server might be slow, and it causes that the Nginx is locked on I/O operations. To avoid locking use example following setup: one worker_precess / per processor core, like:
Worker Processes

To check how many processor cores do you have, run following command:

So here is 4 cores and worker_processes final setup could be following:

Worker Connections
Personally I stick with 1024 worker connections, because I don’t have any reason to raise this value. But if example 4096 connections per second is not enough then it’s possible to try to double this and set 2048 connections per process.

worker_processes final setup could be following:

I have seen some configurations where server admins are used too much Apache and think if I set Nginx worker_processes to 50 and worker_connections to 20000 then my server could handle all traffic once what we get monthly…but yes it’s not true. It’s just wasting of resources and might cause some serious problems…

Nginx Tip 3. – Hide Nginx Server Tokens / Hide Nginx version number

This is good for security reasons hide server tokens / hide Nginx version number, especially, if run some outdated version of Nginx. This is very easy to do just set server_tokens off under http/server/location section, like:

Nginx Tip 4. – Nginx Request / Upload Max Body Size (client_max_body_size)

If you want to allow users upload something or upload personally something over the HTTP then you should maybe increase post size. It can be done with client_max_body_size value which goes underhttp/server/location section. On default it’s 1 Mb, but it can be set example to 20 Mb and also increase buffer size with following configuration:

If you get following error, then you know that client_max_body_size is too low:
“Request Entity Too Large” (413)

Nginx Tip 5. – Nginx Cache Control for Static Files (Browser Cache Control Directives)

Browser caching is import if you want save resources and bandwith. It’s easy setup with Nginx, following is very basic setup where logging (access log and not found log) is turned off and expires headers are set to 360 days.

If you want more complicated headers or some other expiration by filetypes then you could configure those separately.

Nginx Tip 6. – Nginx Pass PHP requests to PHP-FPM

Here you could use default tpc/ip stack or use directly Unix socket connection. You have to also setup PHP-FPM listen exactly same ip:port or unix socket (with Unix socket also socket permission have to be right). Default setup is use ip:port ( you could of course change ips and ports what PHP-FPM listens. Here is very basic configuration with Unix socket example commented out:

It’s also possible to run PHP-FPM another server and Nginx another.

Nginx Tip 7. – Prevent (deny) Access to Hidden Files with Nginx

It’s very common that server root or other public directories have hidden files, which starts with dot (.) and normally those is not intended to site users. Public directories can contain version control files and directories, like .svn, some IDE properties files and .htaccess files. Following deny access and turn off logging for all hidden files.

PHP-FPM Configuration Tips and Tricks

PHP-FPM Tip 1. – PHP-FPM Configuration files

Normally PHP-FPM configuration files are located on /etc/php-fpm.conf file and /etc/php-fpm.d path. This is normally excellent start and all pool configs goes to /etc/php-fpm.d directory. You need to add following include line on your php-fpm.conf file:

PHP-FPM Tip 2. – PHP-FPM Global Configuration Tweaks

Set up emergency_restart_threshold, emergency_restart_interval and process_control_timeout. Default values for these options are totally off, but I think it’s better use these options example like following:

What this mean? So if 10 PHP-FPM child processes exit with SIGSEGV or SIGBUS within 1 minute then PHP-FPM restart automatically. This configuration also sets 10 seconds time limit for child processes to wait for a reaction on signals from master.

PHP-FPM Tip 3. – PHP-FPM Pools Configuration

With PHP-FPM it’s possible to use different pools for different sites and allocate resources very accurately and even use different users and groups for every pool. Following is just example configuration files structure for PHP-FPM pools for three different sites (or actually three different part of same site):

Just example configurations for every pool:



So this is just example howto configure multiple different size pools.

PHP-FPM Tip 4. – PHP-FPM Pool Process Manager (pm) Configuration

Best way to use PHP-FPM process manager is use dynamic process management, so PHP-FPM processes are started only when needed. This is almost same style setup than Nginx worker_processes and worker_connections setup. So very high values does not mean necessarily anything good. Every process eat memory and of course if site have very high traffic and server lot’s of memory then higher values are right choise, but servers, like VPS (Virtual Private Servers) memory is normally limited to 256 Mb, 512 Mb, 1024 Mb. This low RAM is enough to handle even very high traffic (even dozens of requests per second), if it’s used wisely.

It’s good to test how many PHP-FPM processes a server could handle easily, first start Nginx and PHP-FPM and load some PHP pages, preferably all of the heaviest pages. Then check memory usage per PHP-FPM process example with Linux top or htop command. Let’s assume that the server has 512 Mb memory and 220 Mb could be used for PHP-FPM, every process use 24 Mb RAM (some huge content management system with plugins can easily use 20-40 Mb / per PHP page request or even more). Then simply calculate the server max_children value:
220 / 24 = 9.17

So good pm.max_children value is 9. This is based just quick average and later this could be something else when you see longer time memory usage / per process. After quick testing it’s much easier to setuppm.start_servers value, pm.min_spare_servers value and pm.max_spare_servers value.

Final example configuration could be following:

Max request per process is unlimited by default, but it’s good to set some low value, like 200 and avoid some memory issues. This style setup could handle large amount of requests, even if the numbers seems to be small.


Скомуниздено отсюда: http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/



http://www.toptal.com/nodejs/let-loopback-do-it-a-walkthrough-of-the-node-api-framework-you-ve-been-dreaming-of - тута туториал для лупбэка)

https://docs.strongloop.com/display/public/LB/Define+model+relations - от тут мануал закончил читать.







loopback по-русски: https://docs.strongloop.com/display/RU/LoopBack



Что такое git? Основные понятия

Git (произн. «гит») — распределённая система управления версиями файлов. Проект был создан Линусом Торвальдсом для управления разработкой ядра Linux.

Системы управления версиями (Version Control Systems) – это программное обеспечение, призванное автоматизировать работу с историей файла (или группы файлов), обеспечить мониторинг изменений, синхронизацию данных и организовать защищенное хранилище проекта. Короче говоря, основная задача систем управления версиями – упростить работу с изменяющейся информацией.

Распределённые системы управления версиями – это СУВ, главной парадигмой которых является локализация данных каждого разработчика проекта. Иными словами, если в централизованных СУВ все действия, так или иначе, зависят от центрального объекта (сервер), то в распределенных СУВ каждый разработчик хранит собственную ветвь версий всего проекта. Удобство такой системы в том, что каждый разработчик имеет возможность вести работу независимо, время от времени обмениваясь промежуточными вариантами файлов с другими участниками проекта.

Рассмотрим пример: У каждого разработчика на машине есть свой локальный репозиторий – место хранения версий файлов. Работа с данными проекта реализуется над вашим локальным репозиторием, и для этого необязательно поддерживать связь с остальными (пусть даже и главными) ветвями разработки. Связь с другими репозиториями понадобится лишь при изменении/чтении версий файлов других ветвей. При этом каждый участник проекта задает права собственного хранилища на чтение и запись. Таким образом, все ветви в распределенных СУВ равны между собой, и главную из них выделяет координатор. Отличие главной ветви лишь в том, что на неё мысленно будут равняться разработчики.

Запись изменений в репозиторий (commit)

Допустим, у вас имеется репозиторий Git и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать состояния этих изменений (commit) в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить. Запомните, каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (не отслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем слепке состояния проекта; они могут быть не измененными, измененными или подготовленными к коммиту (staged). Все изменения в них, будут отслеживаться. Не отслеживаемые файлы — это всё остальное, любые файлы в вашем рабочем каталоге, которые не входили в ваш последний слепок состояния и не подготовлены к коммиту. Когда вы впервые клонируете репозиторий, все файлы будут отслеживаемые и не измененные, потому что вы только взяли их из хранилища и ничего пока не редактировали. Как только вы отредактируете файлы, Git будет рассматривать их как измененные, т.к. вы изменили их с момента последнего коммита. Вы индексируете (stage) эти изменения и затем фиксируете (делаете коммит) все индексированные изменения.

Что такое ветка?

Ветка (или «branch») — это своеобразное "место" разработки. Например, после клонирования репозитория мы по-умолчанию находимся в ветке master, создаём ветку test (в которую будет всё слито из master), затем делаем в ней какие-то изменения, делаем коммит, а потом переключиться обратно в ветку master. С помощью команды

$ git log

в каждой из веток, можно будет посмотреть все коммиты. В ветке master вы увидите, что ваш коммит из test на ветку не распространяется, и те файлы, которые вы изменили в ветке test будут возвращены к состоянию последнего коммита в ветке master. Таким образом ветка - это что-то вроде текущего состояния вашей разработки.

Работа с git-репозиториями, сведения для начинающих

Настройка git

Первым делом настроим ваше имя и адрес почты. Имя вводите на английском.

$ git config --global user.name "Ваше имя"
$ git config --global user.email "ваше_имя@etersoft.ru"

Ключ --global задаёт сохранение данных для всех репозиториев. Без --global настройки будут сохранены в текущем репозитории. Затем настроим правильное отображение цветов:

$ git config --global color.branch auto
$ git config --global color.diff auto
$ git config --global color.interactive auto
$ git config --global color.status auto

После этого нужно настроить доступ

Работа с локальным репозиторием

Клонирование репозитория

Чтобы начать работать с репозиторием, следует создать копию проекта со всей его историей локально. Нужно создать каталог Projects, перейти в него, а затем клонировать удалённый репозиторий:

$ git clone git.eter:/projects/wine/wine-public-tests.git wine-tests

После этой процедуры репозиторий скопируется в папку wine-test (можно не указывать, тогда репозиторий скопируется в папку, соответствующую названию перед ".git" - в нашем случае это будет wine-public-tests). Если выполнять клонирование с помощью:

$ git clone git://git.etersoft.ru/projects/wine/wine-public-tests.git

то у вас не будет прав на запись, т.е. вы не сможете пушить (опубликовывать) коммиты.

Определение состояния файлов

Основная команда, используемая для определения какие файлы в каком состоянии находятся — это команда git status. Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:

$ git status
# On branch master
nothing to commit (working directory clean)

Это означает, что у вас чистый рабочий каталог, другими словами — в нем нет ни отслеживаемых, ни измененных файлов. Git также не обнаружил не отслеживаемых файлов, в противном случае они бы были перечислены здесь. И наконец, команда сообщает вам на какой ветке (branch) вы сейчас находитесь.

Предположим, вы добавили новый файл в ваш проект, простой README файл. Если этого файла раньше не было, и вы выполните git status, вы увидите не отслеживаемый файл как-то так:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#       README
nothing added to commit but untracked files present (use "git add" to track)

Вы можете видеть, что новый файл README не отслеживаемый, т.к. он находится в секции “Untracked files”. Не отслеживаемый файл обычно означает, что Git нашел файл, отсутствующий в предыдущем коммите. Git не станет добавлять его в ваши коммиты, пока вы явно ему это не укажете. Это предохраняет вас от случайного добавления в репозиторий сгенерированных каких-либо других файлов, которые вы и не думали добавлять.

Добавление файлов в индекс

Для добавления файлов в индекс (временное хранилище изменений) используется команда git add. Чтобы добавить файл README в индекс и начать его отслеживание, выполните:

$ git add README

Если вы снова выполните команду git status, то увидите, что файл README теперь отслеживаемый и индексированный:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#       new file:   README

Вы можете видеть, что файл проиндексирован по тому, что он находится в секции “Changes to be committed”. Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add, будет добавлена в историю коммитов (git log).

Отредактируйте какой-нибудь .cpp файл, добавьте в него, например, комментарий и сохраните. Выполнив команду git status вы увидите, что ваш отредактированный файл находится в секции “Changed but not updated” — это означает, что отслеживаемый файл был изменен в рабочем каталоге, но пока не проиндексирован. Чтобы проиндексировать его, необходимо выполнить команду

$ git add ИМЯ_ФАЙЛА

git add - многофункциональная команда, она используется для добавления отслеживаемых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния.


$ git add .

вносит в индексе все изменения, включая все обновлённые и новые файлы

Удаление файлов из индекса. Добавление удалённых файлов в индекс

  • Удаление файла из индекса: Если вы внесли изменения в два файла и хотите сделать коммит с одним из них, но случайно набрали git add . и проиндексировали оба файла, то вам поможет команда git reset:
$ git reset ИМЯ_ФАЙЛА

После неё текущее состояние вашего файл останется низменным, но он не будет занесён в индекс.

  • Добавление удалённого файла: Если вы просто удалите файл из каталога, он будет показан в секции “Changed but not updated” команды git status, т.е. он будет не проиндексирован. Чтобы добавить удаление в индекс Git, то после удаления файла, выполните команду:
$ git rm ИМЯ_ФАЙЛА
  • Если у вас большое количество удалённых, но не добавленных в индекс файлов, то вы можете добавить их командой:
$ git add -A
  • Если вы хотите удалить файл из индекса и сделать его не отслеживаемым, но при этом оставить его в каталоге, то выполните:
$ git rm --cached ИМЯ_ФАЙЛА

Отмена текущих изменений в файле

Если вы поняли, что не хотите оставлять изменения внесённые в файл, то вернуть то состояние, в котором находился файл во время последнего коммита, выполните:

$ git checkout -- ИМЯ_ФАЙЛА

Будьте осторожны, т.к. все сделанные вами изменения в этом файле пропадут.

Просмотр (не)индексированных изменений

Если вам хочется знать, что конкретно поменялось, а не только какие файлы были изменены — вы можете использовать команду git diff. Допустим, вы снова изменили ".cpp" файл без индексирования (без git add). Чтобы увидеть, что же вы изменили, но пока не проиндексировали, выполните:

$ git diff

Вы увидите изменения, которые вы внесли в файл. Чтобы просмотреть изменения в файлах, которые вы уже добавили в индекс, выполните:

$ git diff --cached

Работа с ветками

Просмотр списка веток

Чтобы просмотреть список веток, выполните:

git branch

после чего, вы увидите имеющиеся ветки

$ git branch
* master
Создание веток

Когда вы создаёте ветку, то она создаёт независимый клон вашей текущей ветки (не индексируемые изменения не клонируются)

Чтобы создать ветку test, не переключаясь в неё, выполните:

$ git branch test

Чтобы создать ветку test и переключиться в неё, выполните:

$ git checkout -b test
Перемещение по веткам

Чтобы перейти в ветку master, выполните:

$ git checkout master

Если в текущей ветке были какие-то изменения по сравнению с последним коммитом в ветке, то команда откажется производить переключение, дабы не потерять произведенную работу. Проигнорировать этот факт позволяет ключ -f:

$ git checkout -f master
Сохранение не индексированных изменений в текущей ветке и переход в другую

Если вы не хотите делать коммит, но вам нужно перейти в другую ветку, не теряя текущих изменений вы должны сделать:

$ $ git stash save 
Saved "WIP on master: e71813e..."

После этого в git diff пропадут ваши изменения и вы можете перейти в другую ветку

Для просмотра сохранённых изменений:

$ git stash list
stash@{0}: WIP on master: e71813e..."

Чтобы применить сохраненные изменения и вернуть рабочее состояние, выполните:

$ git stash apply stash@{0}

Чтобы удалить конкретный сохранённый стэш, выполните:

$ git stash drop stash@{0}

Чтобы удалить все сохранённые стэши, выполните:

$ git stash clear
Удаление ветки

Если у вас нет не индексированных изменений (изменили что-то, но ещё не добавляли в индекс с помощью git add),то удалить ветку можно так:

$ git branch -d ИМЯ_ВЕТКИ

Если вы хотите удалить ветку, и потерять текущие изменения, то выполните:

$ git branch -D ИМЯ_ВЕТКИ
Переименование ветки

Переименовать ветку можно так:

$ git branch -m НОВОЕ_ИМЯ
Слияние веток и конфликты

Команда попробует объединить текущую ветку и ветку test:

$ git merge test

Иногда процесс слияния не идет гладко. Если вы изменили одну и ту же часть файла по-разному в двух ветках, которые собираетесь объединить, Git не сможет сделать это чисто и выдаст конфликт слияния:

$ git merge test
Auto-merging ......
CONFLICT (content): Merge conflict in ......
Automatic merge failed; fix conflicts and then commit the result.

Git не создал новый коммит для слияния. Он приостановил этот процесс до тех пор, пока вы не разрешите конфликт. Если вы хотите посмотреть, какие файлы не прошли слияние (на любом этапе после возникновения конфликта), можете выполнить команду git status:

$ git status
ИМЯ_ФАЙЛА: needs merge
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#       unmerged:   ИМЯ_ФАЙЛА

Всё, что имеет отношение к конфликту слияния и что не было разрешено, отмечено как unmerged. Git добавляет стандартные маркеры к файлам, которые имеют конфликт, так что вы можете открыть их вручную и разрешить эти конфликты. Ваш файл содержит секцию, которая выглядит примерно так:

// bla-bla-bla
// test

В верхней части блока (всё что выше =======) это версия из HEAD (вашей ветки master, так как именно на неё вы перешли перед выполнением команды merge), всё что находится в нижней части ― версия в ветке test. Чтобы разрешить конфликт вы должны либо выбрать одну из этих частей, либо как-то объединить содержимое по своему усмотрению. Отредактируйте и удалите ====== и >>>>>>>. Затем выполните git add. Индексирование будет означать для Git, что все конфликты в файле теперь разрешены.

Работа с коммитами

Добавление нового коммита, просмотр истории

Теперь, когда ваш индекс настроен так как вам и хотелось, вы можете зафиксировать ваши изменения - сделать коммит. Запомните: всё, что до сих пор не проиндексировано — любые файлы, созданные или измененные вами, и для которых вы не выполнили git add после момента редактирования — не войдут в этот коммит. Выполните команду:

$ git commit

После этого откроется текстовой редактор и будет отображено что-то вроде этого:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#       new file:   README
#       modified:   КАКОЙ-ТО_ФАЙЛ
".git/COMMIT_EDITMSG" 10L, 283C

Вам нужно будет ввести комментарий для коммита, после чего сохраниться.

Есть ещё другой способ, который позволит ввести комментарий сразу из командной строки:

$ git commit -m "ВАШ КОММЕНТАРИЙ"

Есть ещё команда, которая автоматически проиндексирует изменения во всех изменённых файлах проекта. Новые файлы при этом индексироваться не будут, но удаление файлов будет учтено. Т.е. вы можете обойтись без git add.

$ git commit -a -m "ВАШ КОММЕНТАРИЙ"

Можно без параметра "-m", чтобы посмотреть файлы, которые ввойдут в коммит.

Чтобы просмотреть историю коммитов, выполните уже знакомую команду:

$ git log

Чтобы просмотреть изменения, сделанные в последнем коммите, выполните:

$ git show

Так же во многих командах можно указывать номер коммита, начиная от верхнего, либо его собственный номер, который можно посмотреть в git log. Например, эта команда покажет третий сверху коммит:

$ git show HEAD~2

Как видите, в данном случае число в HEAD~, обозначает номер коммита, не учитывая самый последний (верхний).

Создание отменяющего коммита

Если вы сделали коммит с ошибкой, то можно его отредактировать (как это сделать, мы разберём дальше), но делать это нужно лишь в том случае, если вы не опубликовали его в какой-нибудь удалённый репозиторий, с которым работают другие люди. В ином случае лучше создать коммит, который отменит предыдущий и вернёт вас в старое состояние. Как это сделать:

$ git revert HEAD

Если вам нужно отменить четвёртый коммит, то выполните:

$ git revert HEAD~3
Сброс состояния проекта, отмена, удаление последних коммитов

Помимо работы с индексом, git reset позволяет сбросить состояние проекта до какого-либо коммита в истории. В таком случае вместе с командой используются различные ключи (soft, hard и т.п.).

  • --soft :
$ git reset --soft HEAD^

Команда отменит последний коммит и вернёт вас к тому состоянию, когда вы добавили все нужные изменения в индекс (git add), но ещё не совершили коммит. Команда не сбрасывает текущие индекс и не индексированные изменения. Если до выполнения reset вы добавляли в индекс какие-то файлы, то они войдут в секцию "Changes to be committed"!

Если состояние сбрасывается на несколько коммитов, то плюс ко всему будут добавлены в индекс и их изменения (секция "Changes to be committed").

  • --hard : Удаляет коммит и в любом случае сбросит все индексированные и не индексированные изменения, а так же обновит файлы в директории до состояния нужного коммита, т.е. команда:
$ git reset --hard HEAD~2

удалит два последних коммита и вернёт вас к такому состоянию проекта, если бы вы только что совершили третий сверху коммит.

  • --mixed : (она же просто git reset): Тоже самое, что и soft, только при этом сбрасываются изменения занесённые в индекс (git add)
  • --merge :
$ git reset --merge HEAD~2

Команда работает в том случае, если у вас нет не индексированных изменений тех файлов, которые изменяются в двух последних коммитах.

Отменяются два последних коммита. Сбрасывается индекс и обновляются файлы в директории до состояния третьего коммита сверху. При этом сохраняются изменения в файлах, которые не добавлялись в индекс (не git add).

Редактирование последнего коммита
  • Если вы что-то напутали с комментарием к последнему коммиту, выполните команду и поменяйте комментарий:
$ git commit --amend

Если сразу после совершения коммита, вы ничего не добавляли в индекс (git add), то следуйте инструкции. В ином случае, вам придётся удалить из него ненужные файлы:

  • Если вы сделали не все изменения, или забыли добавить в коммит какие-то файлы, то выполните нужные действия, а потом добавьте эти файлы в индекс (git add), затем снова выполните $ git commit --amend и сохраните изменения.
Редактирование нескольких или какого-то одного коммита из истории

Допустим, вам надо отредактировать 3 последних коммита, выполните:

$ git rebase -i HEAD~3 

Команда выполнится в интерактивном режиме. Можно заметить, что в данном случае, число в команде HEAD~ включает в себя самый верхний коммит. Откроется редактор, который отобразит нечто подобное:

# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x <cmd>, exec <cmd> = Run a shell command <cmd>, and stop if it fails
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.

Обратите внимание, что первым идёт коммит, который является самым старым из выбранных вами коммитов!

Для того, чтобы отредактировать нужный коммит, замените перед номером коммита слово pick на edit. Когда вы сохраните изменения и выйдите из редактора, Git вернёт вас к первому из тех коммитов, которые вы хотите отредактировать. В итоге вы увидите такое:

$ git rebase -i HEAD~3
  Stopped at НОМЕР_КОММИТА... updated the gemspec to hopefully work better
  You can amend the commit now, with

        git commit --amend

  Once you’re satisfied with your changes, run

        git rebase --continue

Далее делаем нужные изменения, добавляем изменения в индекс (git add), а затем выполняем, как указано в инструкции, команду git commit --amend. После этого, выполняем:

git rebase --continue

После чего, Git автоматически применит следующие коммиты. Если у вас несколько редактируемых коммитов, то вам снова придётся выполнить то, о чем я писал выше. В итоге Git покажет всё ли удачно применилось.

Редактирование комментария к коммиту

Если, например, надо исправить комментарий к 6 сверху коммиту, то выполняем:

$ git rebase -i HEAD~6

Затем меняем у нужного коммита pick на reword. Исправляем комментарий, сохраняемся, выходим. Git автоматически должен всё поменять.

Изменение порядка коммитов. Удаление коммитов

Изменение порядка коммитов в некоторых случаях может привести к большим проблемам, поэтому стоит задуматься - так уж необходимо менять коммиты местами?

Выбираем нужный диапазон коммитов, например - последние шесть ,и делаем:

$ git rebase -i HEAD~6

Меняем строчки нужных коммитов местами, только не забудьте что первыми идут более старые коммиты, сохраняемся и выходим.

Чтобы удалить ненужный коммит, просто удаляем строчку с коммитом.

Слияние коммитов в один

Выбираем нужный диапазон коммитов, например - последние 6, и решаем слить три каких-нибудь коммита в один:

$ git rebase -i HEAD~6

Затем меняем pick на squash у нужных коммитов, сохраняем, выходим и видим что-то наподобие:

# This is a combination of 3 commits.
# The first commit's message is:


# This is the 2nd commit message:


# This is the 3rd commit message:


Если хотите, можно оставить только один комментарий, который будет у нового коммита, для этого нужно оставить комментарий после

# The first commit's message is:

а в остальных коммит мессаджах убрать.

Разбиение коммита на несколько

Предположим, что вы хотите разбить какой-то коммит в последних шести на несколько. Как всегда, выполняем:

$ git rebase -i HEAD~6

Меняем у нужного коммита pick на edit. После этого делаем:

$ git reset HEAD^

Эта команда отменяет коммит, который вы собираетесь разбивать и убирает из индекса все изменённые файлы. Вам остаётся только добавить файлы с нужными изменениями (git add), затем сделать коммит. Потом снова добавить нужные файлы, и снова сделать коммит. И так до тех пор, пока вы не разобьёте свой коммит на необходимое колличество коммитов. После этого нужно выполнить:

$ git rebase --continue

Всё это будет выглядеть примерно так:

$ git reset HEAD^
$ git add README
$ git commit -m 'New changes in README'
$ git add test.cpp
$ git commit -m 'Added test'
$ git rebase --continue
Перенос коммитов из другой ветки

Предположим, разработчик завел дополнительную ветку для разработки отдельной возможности и совершил в ней несколько коммитов. Одновременно по какой-либо причине в основной ветке также были совершены коммиты: например, в нее были залиты изменения с удаленного сервера; либо сам разработчик совершал в ней коммиты. В принципе, можно обойтись обычным git merge. Но тогда усложняется сама линия разработки, что бывает нежелательно в слишком больших проектах, где участвует множество разработчиков. Предположим, имеется две ветки: master и test, в каждой из которых было совершенно несколько коммитов начиная с момента ветвления. Команда git rebase берет коммиты из ветки test и накладывает их на последний коммит ветки master: вариант, в котором явно указывается, что и куда прикладывается

$ git rebase master topic

А здесь на master накладывается ветка, активная в настоящий момент :

$ git rebase master

После использования команды история становится линейной. При возникновении конфликтов при поочередном накладывании коммитов работа команды будет останавливаться, а в проблемные местах файлов появятся соответствующие метки. После редактирования — разрешения конфликтов — файлы следует внести в индекс командой git add и продолжить наложение следующих коммитов командой

$ git rebase --continue 

Альтернативными выходами будут команды

$ git rebase --skip 

пропустить наложение коммита и перейти к следующему или

$ git rebase --abort 

отмена работы команды и всех внесенных изменений.

С ключом -i (--interactive) команда будет работать в интерактивном режиме. Пользователю будет предоставлена возможность определить порядок внесения изменений, автоматически будет вызывать редактор для разрешения конфликтов и так далее.

Работа с удалённым репозиторием

Удалённый репозиторий — это модификация проекта, которая хранится в интернете или ещё где-то в сети. УР обычно доступен для вас либо только на чтение, либо на чтение и запись. Совместная работа включает в себя помещение (push) и получение (pull) данных и из них тогда, когда нужно обменяться результатами работы.

Отображение удалённых репозиториев

Чтобы просмотреть какие удалённые серверы у вас уже настроены, следует выполнить команду

$ git remote 

Она перечисляет весь список имён-сокращений (псевдонимов) удалённых репозиториев, созданных в текущем репозитории. Если вы склонировали ваш репозиторий, у вас должен отобразиться по крайней мере origin — это имя по умолчанию, которое Git присваивает серверу, с которого вы склонировали.

Чтобы посмотреть какому URL соответствует сокращённое именя в Git, можно указать команде опцию -v:

$ git remote -v
origin  git.eter:/projects/wine/wine-public-tests.git

Если у вас больше одного удалённого репозитория, команда покажет их все.

Создание и добавление удалённого репозитория

Создадим пустой удалённый репозиторий:

$ ssh git.eter init-db packages/ИМЯ_РЕПОЗИТОРИЯ.git

Имя лучше указывать такое же как у репозитория, который вы cклонировали.

Чтобы добавить УР под именем-сокращением, выполните:

$ git remote add ВАШЕ_ИМЯ-СОКРАЩЕНИЕ git.eter:/people/ВАШЕ_ИМЯ/packages/ИМЯ_РЕПОЗИТОРИЯ.git

Так же можно указывать адрес локального репозитория.

Забрать изменения из удалённого репозитория

  • Например, если вы хотите извлечь (fetch) всю информацию, которая есть в каком-то удалённом репозитории, но нет в вашем, вы можете выполнить:

Данная команда связывается с указанным удалённым проектом и забирает все те данные проекта, которых у вас ещё нет. После того как вы выполнили команду, у вас должны появиться ссылки на все ветки из этого удалённого проекта. Теперь эти ветки в любой момент могут быть просмотрены или слиты. Ветка master теперь доступна локально как ПСЕВДОНИМ/master. Вы можете слить (merge) её в одну из ваших веток, или можете перейти на эту ветку и просмотреть её.

Когда вы клонируете репозиторий, команда git clone автоматически добавляет этот удалённый репозиторий под именем origin. Таким образом git fetch origin извлекает все наработки, отправленные (push) на этот сервер после того, как вы склонировали его (или получили изменения с помощью fetch). Важно отметить, что команда fetch забирает данные в ваш локальный репозиторий, но не сливает их с какими-либо вашими наработками, и не модифицирует то, над чем вы работаете в данный момент. Вам необходимо вручную слить эти данные с вашими, когда вы будете готовы.

  • Если у вас есть ветка настроенная на отслеживание удалённой ветки (см. работу с удалёнными ветками), то вы можете использовать команду
$ git pull 

Она автоматически извлекает и затем сливает данные из удалённой ветки в вашу текущую ветку. Этот способ может для вас оказаться более простым или более удобным. К тому же по умолчанию команда git clone автоматически настраивает вашу локальную ветку master на отслеживание удалённой ветки master на сервере, с которого вы клонировали (подразумевается, что на удалённом сервере есть ветка master). Выполнение git pull как правило извлекает (fetch) данные с сервера, с которого вы изначально склонировали, и автоматически пытается слить (merge) их с кодом, над которым вы в данный момент работаете.

Запушить изменения в удалённый репозиторий

Когда ваш проект достигает момента, когда вы хотите поделиться наработками, вам необходимо отправить (push) их в удалённый репозиторий. Команда для этого действия простая:


Чтобы отправить вашу ветку master на сервер origin, вы можете выполнить следующую команду:

$ git push origin master

Эта команда срабатывает только в случае, если вы клонировали с сервера, на котором у вас есть права на запись, и если никто другой с тех пор не выполнял команду push. Если вы и кто-то ещё одновременно клонируете, затем он выполняет команду push, а затем команду push выполняете вы, то запушить не получится. Вам придётся сначала забрать изменения (pull) и объединить с вашими. Только после этого вам будет позволено выполнить push.

Получение информации об удалённом репозитории

Если хотите получить побольше информации об одном из удалённых репозиториев, вы можете использовать команду

$ git remote show ПСЕВДОНИМ_УД_СЕРВЕРА

Если вы выполните эту команду с именем origin, вы получите что-то подобное:

$ git remote show origin
* remote origin
  Fetch URL: git://git.etersoft.ru/projects/wine/wine-public-tests.git
  Push  URL: git://git.etersoft.ru/projects/wine/wine-public-tests.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Она выдаёт URL удалённого репозитория, а также информацию об отслеживаемых ветках. Эта команда любезно сообщает вам, что, если вы находясь на ветке master, выполните git pull, ветка master с удалённого сервера будет автоматически влита в вашу сразу после получения всех необходимых данных. Она также выдаёт список всех полученных ею ссылок. В некоторых случаях команда может показать какая именно локальная ветка будет отправлена на удалённый сервер по умолчанию при выполнении git push. Она также показывает каких веток с удалённого сервера у вас ещё нет, какие ветки всё ещё есть у вас, но уже удалены на сервере. И для нескольких веток показано какие удалённые ветки будут в них влиты при выполнении git pull.

Переименовывание удалённого репозитория

Например, если вы хотите переименовать псевдоним удалённого репозитория test в etersoft, вы можете сделать это следующим образом:

$ git remote rename test etersoft
$ git remote

Стоит упомянуть, что это также меняет для вас имена удалённых веток. То, к чему вы обращались как test/master, стало etersoft/master.

Если вы хотите переименовать сам удалённый репозиторий, который вы создали, а он обычно размещается по адресу: http://git.etersoft.ru/people/ВАШ_НИК/packages/ИМЯ_РЕПОЗИТОРИЯ.git

то выполните команду:

$ ssh git.eter mv-db СТАРОЕ_ИМЯ НОВОЕ_ИМЯ

Удаление удалённого репозитория

Если по какой-то причине вы хотите удалить ссылку (псевдоним), вы можете использовать:

$ git remote rm test 
$ git remote

Если вы хотите удалить сам репозиторий, то выполните:

$ ssh git.eter rm-db ИМЯ_РЕПОЗИТОРИЯ

Работа с удалёнными ветками

Удалённые ветки ― это ссылки на состояние веток в ваших удалённых репозиториях. Это локальные ветки, которые нельзя перемещать; они двигаются автоматически всякий раз, когда вы осуществляете связь по сети. Удалённые ветки действуют как закладки для напоминания о том, где ветки в удалённых репозиториях находились во время последнего подключения к ним. Они выглядят как (имя удал. репоз.)/(ветка). Например, если вы хотите посмотреть, как выглядела ветка master на сервере origin во время последнего соединения с ним, проверьте ветку origin/master.

Просмотр удалённых веток

Чтобы просмотреть список удалённых веток, вам нужно выполнить команду:

$ git branch -r
origin/HEAD -> origin/master
Удаление ветки в удалённом репозитории

Чтобы удалить ветку, выполните:

Слияние ветки из удалённого репозитория

Чтобы слить наработки в вашу текущую рабочую ветку, можете выполнить:


Если вы хотите иметь собственную ветку, над которой вы сможете работать, можете создать её на основе удалённой ветки:

Отслеживание веток

Получение локальной ветки с помощью git checkout из удалённой ветки автоматически создаёт то, что называется отслеживаемой веткой. Отслеживаемые ветки это локальные ветки, которые напрямую связаны с удалённой веткой. Если находясь на отслеживаемой ветке, вы наберёте git push, Git автоматически знает на какой сервер и в какую ветку отправлять изменения. Аналогично, выполнение git pull на одной из таких веток сначала получает все удалённые ссылки, а затем автоматически делает слияние с соответствующей удалённой веткой. При клонировании репозитория, как правило, автоматически создаётся ветка master, которая отслеживает origin/master. Вот почемуgit push и git pull работают и не требуют других аргументов. Однако, если хотите, можете настроить другие отслеживаемые ветки — те, которые не отслеживают ветки в origin, и те, которые не отслеживают ветку master. Простой случай это тот пример, который вы видели выше — выполнение:


Так же можно использовать ключ --track. В общем в Git должно отобразиться сообщение, что ветка будет отслеживаться.

$ git checkout -b ab origin/test
Branch sf set up to track remote branch refs/remotes/origin/serverfix

Работа с патчами

Создание патча:

git format-patch ID

ID – идентификатор предыдущего коммита. Коммиты, более новые, чем указанный, будут записаны в файлы. В результате мы должны увидеть:


Посмотреть сделанные коммиты можно через:

git log

Пример, в первой строчке – ID коммита:

commit 53333771aae4888ee2e8373cec0abb06e3d1c290
Author: sergeym <sergeym@etersoft.ru>
Date:   Sat Mar 17 15:29:26 2012 +0400

Если надо, чтобы в тему письма включался номер патча в серии, можно использовать параметр -n:

git format-patch -n ID

В результате получится нечто вроде:

Subject: [PATCH 02/22] hal: Add stub for HalTranslateBusAddress.

Слово патч можно заменить на любое другое с помощью параметра --subject-prefix:

git format-patch -n --subject-prefix=eterhack ID


Subject: [eterhack 02/22] hal: Add stub for HalTranslateBusAddress.

Сгенерированные патчи можно отправить по почте с помощью команды

git send-email --from 'Your Name <yourname@etersoft.ru>' --to 'wine-patches@lists.etersoft.ru' 0*.txt

Для подключения(приложения) патча следует пользоваться командой

git am ИМЯ_ПАТЧА.patch

Патч применен:


Если в процессе приложения патча произошла ошибка, то при обновлении репозитория (pull) может появиться ошибка:

It looks like git-am is in progress. Cannot rebase.

Для избежания этой ошибки после неудачного приложения патча следует осуществить следующую команду:

git am --abort


Too many open files

текущее число открытых файлов:
cat /proc/sys/fs/file-nr
открытыеоткрытые, но не используемыемаксимально возможное количество открытых

Увеличить максимальное:
vim /etc/sysctl.conf
fs.file-max = 9999999
sysctl -p

Увеличить для mysql соответственно количество файлов и процессов:
vim /etc/security/limits.conf
mysql soft nofile 28192
mysql hard nofile 28192
mysql soft nproc 20240
mysql hard nproc 20240


Конвертация файла из cp-1251 в utf-8

iconv -f WINDOWS-1251 -t UTF-8 src_filename > dst_filename


Интересная особенность FF и Chrome

Если использовать плагин jquery для получения cookies, то не установленную куку FF возвращает как пустую строку, а chrome - как null.


Путь до запускаемого скрипта

Для красивого решения проблемы нужно знать всего три вещи:
Путь до выполняющегося скрипта можно узнать с помощью $0, но проблема в том, что он относительный, т.е. если вы запустите скрипт как ./script.sh, то и $0 будет содержать ./script.sh
Команда readlink с параметром -e решит сразу две проблемы: во-первых она вернет полный путь до файла скрипта, если вы воспользовались для запуска символической ссылкой (даже если это была цепочка симлинков), а во-вторых преобразует относительный путь, если такой получен с помощью $0, в абсолютный
Чтобы избавиться от имени файла скрипта в конце абсолютного пути, нужно воспользоваться командой dirname


# полный путь до скрипта
ABSOLUTE_FILENAME=`readlink -e "$0"`
# каталог в котором лежит скрипт

# запуск "соседних" скриптов

в php есть константа __DIR__


добавляются лишние символы в ответе сервера nginx

добавляются лишние символы в ответе сервера nginx.
Бэкэндом выступает apache.
Что-то вроде 23af ... 0

SetEnv force-response-1.0 1
SetEnv downgrade-1.0 1

BrowserMatch ".*" downgrade-1.0 force-response-1.0


Ошибка “child pid XXXXX exit signal Segmentation fault (11)”

Как бороться?
Ставим отладчик:
yum install gdb.x86_64
В добавляем файлик /etc/httpd/conf.d/debug.conf
с таким содержанием:
CoreDumpDirectory /tmp
После чего перечитываем конфиг апача:

/etc/init.d/httpd configtest
/etc/init.d/httpd graceful

Всё. Теперь запускаем чтение файла логов и ждём пока отвалится процесс:
tail -f /var/log/httpd/error_log

Собственно, должно быть что-то вроде такого:
[notice] child pid 15774 exit signal Segmentation fault (11), possible coredump in /tmp

Это значит, что у нас теперь есть "слепок" падения.
Натравим на него наш отладчик и посмотрим, что там есть:
gdb httpd /tmp/core.xxx(PID)