0

git hooks server side output only transmits on a newline. I want to configure a custom task and print real-time output on the same line. How can I achieve that? I tried sys.stdout.flush but it transmits everything once complete. It does work in real-time if I add a newline. I want something like

Step A)Started......Completed

with each '.' appended after a given time.

My current code looks like the following and it outputs only when the method is completed.

import sys, time, os


def print_realtime():
    sys.stdout.write('Started.')
    sys.stdout.flush()
    time.sleep(1)
    for i in range(1, 15):
        sys.stdout.write('.')
        sys.stdout.flush()
        time.sleep(0.5)

if __name__ == "__main__":
    print_realtime()

However, it works in realtime if I append '\n' like:

sys.stdout.write('.\n')
torek
  • 448,244
  • 59
  • 642
  • 775
  • Welcome at Stackoverflow. Unfortunately I can't comprehend the nature of the problem. Please have a look at the SO guide on how to provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). If you follow this guideline you will be much more likely getting useful answers. – MrLeeh May 23 '17 at 07:54
  • Hi @MrLeeh I updated the question. Is it clear now? – Anamika Singh May 23 '17 at 08:25
  • That's still not a [mcve]. An MCVE would be a *complete Python program* that one could set up as a Git hook to demonstrate the problem. (Probably you should strip out all the ProcessPoolExecutor and logging code and just have a function that writes to stdout, unless that makes the problem go away, in which case you have a new clue.) – torek May 23 '17 at 08:51
  • I added a python program which could be setup as git hook. If I execute the program directly it works fine appending '.' in real-time but when I set it up as pre-receive hook it just waits and prints everything at the end. Not sure what has to be changed. – Anamika Singh May 23 '17 at 09:47

1 Answers1

1

The problem comes down to the fact that Git itself does not print accumulated remote: text until the remote sends either a newline or carriage return.

Hence, if we change your inner loop to read:

for i in range(1, 15):
    sys.stdout.write('.' * i + '\r')
    sys.stdout.flush()
    time.sleep(0.5)

you will see the effect you desire.

Note that the \r moves the print position back to just after the word remote:, so we must repeat what we have printed so far (hence the need to print first one ., then two .s, then three, and so on).

torek
  • 448,244
  • 59
  • 642
  • 775